# Conflicts:
#	platform/Windows/exhumed.vcxproj
#	platform/Windows/exhumed.vcxproj.filters
This commit is contained in:
nukeykt 2019-08-26 12:59:14 +09:00 committed by Christoph Oelckers
parent 728635c1c0
commit 936ce5a866
143 changed files with 44126 additions and 0 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

View file

@ -0,0 +1 @@
#include "eduke32_icon.c"

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View file

@ -0,0 +1,72 @@
#define NEED_COMMCTRL_H
#include "../../build/include/windows_inc.h"
#include "../../build/include/startwin.editor.h"
RSRC_ICON ICON "build_icon.ico"
RSRC_BMP BITMAP "build.bmp"
WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 260, 200
STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU
CAPTION "Startup"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE, 0, 0, 66, 172
CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 250, 170
CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 180, 48, 14
CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 207, 180, 48, 14
CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32
END
WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 279, 168
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
CAPTION "Dialog"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "&2D Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 8, 50, 8
CONTROL "", IDC2DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 6, 80, 56
CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 148, 8, 49, 10
CONTROL "&3D Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 24, 50, 8
CONTROL "", IDC3DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 22, 80, 56
CONTROL "&Always show this window at startup", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8
END
#define FILEVER 1,9,9,9
#define PRODUCTVER 1,9,9,9
#define STRFILEVER "2.0.0devel\0"
#define STRPRODUCTVER "2.0.0devel\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION FILEVER
PRODUCTVERSION PRODUCTVER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Mapster32 for EDuke32"
VALUE "FileVersion", STRFILEVER
VALUE "InternalName", "Mapster32"
VALUE "LegalCopyright", "Copyright © 2018 EDuke32 Developers, 1996, 2003 3D Realms Entertainment"
VALUE "LegalTrademarks", "Duke Nukem® is a Registered Trademark of Gearbox Software, LLC."
VALUE "OriginalFilename", "mapster32.exe"
VALUE "ProductName", "Mapster32"
VALUE "ProductVersion", STRPRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
1 24 "manifest.build.xml"

View file

@ -0,0 +1,20 @@
#include "sdl_inc.h"
#include "sdlappicon.h"
static Uint8 sdlappicon_pixels[] = {
#if defined _WIN32 && SDL_MAJOR_VERSION==1
# include "eduke32_icon_32px.c"
#else
# include "eduke32_icon_48px.c"
#endif
};
struct sdlappicon sdlappicon = {
#if defined _WIN32 && SDL_MAJOR_VERSION==1
32,32,
#else
48,48,
#endif
sdlappicon_pixels
};

View file

@ -0,0 +1,200 @@
/* GIMP RGBA C-Source image dump (eduke32_icon_32px.c) */
#if 0
static const struct {
unsigned int width;
unsigned int height;
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
unsigned char pixel_data[32 * 32 * 4 + 1];
} sdlappicon = {
32, 32, 4,
#endif
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\11\210\377\33\1\204\377]\15\205\377\225+\224\377\301A\237\377\330"
"O\246\377\346M\245\377\3469\233\377\330%\221\377\301\21\207\377\225\11\203"
"\377]\11}\377\33\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\5\201\3772\25\211\377\240M\245\377\351\236\315\376\377\307"
"\343\377\377\343\361\377\377\365\373\377\377\363\371\377\377\345\362\377"
"\377\276\336\376\377\242\317\376\377\217\306\377\377r\267\376\377=\235\377"
"\351\23\210\377\240\5\201\3772\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1"
"s\377\7\15\205\377\214E\241\377\371\255\326\377\377\361\370\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\375\376\377\377\351\364\377\377\325\352\377\377\274\335\376\377\261\326"
"\377\377\263\331\377\377\236\315\376\377I\243\377\371\7\202\377\214\1s\377"
"\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\17\206\3772\27\212\377\320v\271\376\377\305\342\377\377"
"\335\355\377\377\375\376\377\377\377\377\377\377\361\367\377\377\307\343"
"\377\377\244\320\376\377\215\305\377\377\207\302\377\377\221\307\377\377"
"\261\330\377\377\321\350\377\377\321\350\377\377\325\352\377\377\327\353"
"\377\377\345\361\377\377\242\317\376\377\31\213\377\320\5\201\3772\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\13\204"
"\377/\35\215\377\350v\271\376\377\240\316\376\377\265\332\377\377\357\367"
"\377\377\312\344\376\377\200\276\376\377M\245\377\3777\232\377\377/\226\377"
"\377\37\216\377\377\21\207\377\377\11\203\377\377\17\206\377\377)\223\377"
"\377j\263\376\377\303\341\377\377\361\370\377\377\355\366\377\377\377\377"
"\377\377\303\341\377\377+\224\377\350\5\201\377/\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\21\207\377,\33\214\377\360p\266\376\377"
"\200\276\376\377\276\336\376\377\325\347\377\377`\256\376\377\21\207\377"
"\377\27\212\377\377/\226\377\3777\232\377\3779\232\375\3777\231\375\377$"
"\217\374\377\20\206\376\377\6\201\376\377\0~\376\377\0\203\376\377\21\207"
"\377\377n\265\376\377\357\367\377\377\377\377\377\377\377\377\377\377\324"
"\351\376\377)\223\377\360\5\201\377,\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\1g\377\5\25\211\377\322l\264\376\377x\272\376\377\255\326\377\377\305"
"\340\377\3777\234\373\377\1\220\377\377\1\204\377\377\37\216\377\377;\233"
"\375\377A\236\375\377A\236\375\377;\233\375\377&\220\374\377\27\211\375\377"
"\12\203\376\377\10\202\376\377\20\206\376\377\10\202\376\377\15\205\377\377"
"S\250\377\377\337\357\377\377\371\374\377\377\335\355\377\377\244\320\376"
"\377\31\213\377\322\1g\377\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\11\203\377\213"
"h\262\376\377\231\313\377\377\274\335\376\377\300\335\376\377\16\205\364"
"\377\0\205\354\377\0\207\372\377\\\253\374\377\\\253\374\377&\220\374\377"
";\233\375\377=\234\375\3773\227\375\377$\217\374\377\20\206\376\377\12\203"
"\376\377\10\202\376\3773\227\375\377^\254\374\377&\220\374\377\27\212\377"
"\377+\224\377\377\315\346\377\377\343\361\377\377\314\345\376\377~\275\376"
"\377\7\202\377\213\0\0\0\0\0\0\0\0\0\0\0\0\5\201\377+9\233\377\372\261\330"
"\377\377\257\325\377\377\325\351\377\377$\215\370\377\0\203\350\377\0\177"
"\352\377h\262\376\377\364\370\376\377\312\344\376\377\27\211\375\377\5x\343"
"\377\6n\316\377\3d\267\377\2b\264\377\7i\305\377\6r\326\377\1\204\363\377"
"\232\313\376\377\376\376\376\377\213\302\373\377\27\211\375\377\1\177\377"
"\3773\230\377\377\335\355\377\377\274\335\376\377\255\326\377\377;\234\377"
"\372\13\204\377+\0\0\0\0\0\0\0\0\21\207\377\242\227\312\377\377\312\344\376"
"\377\345\361\377\377Z\253\376\377\0\217\376\377\0\206\370\377e\260\375\377"
"\352\364\376\377\213\302\373\377\251\323\375\377R\231\342\377\1U\217\377"
"\0P\232\377\0Q\234\377\0Q\234\377\1S\237\377\1R\213\377\7o\317\377\273\332"
"\375\377\356\365\376\377\376\376\376\377y\272\375\377\1\177\377\377\1\212"
"\377\377X\252\376\377\325\352\377\377\236\315\376\377|\274\376\377\25\211"
"\377\242\0\0\0\0\13\204\377\26?\236\377\361\314\345\376\377\341\361\377\377"
"\303\341\377\377\7\202\377\377\0\211\376\377D\240\376\377\352\364\376\377"
"\217\305\375\3773\227\375\377\302\340\376\377\326\352\376\377\3d\267\377"
"\0V\230\377\1T\241\377\1T\241\377\0Q\234\377\0U\226\377\214\276\362\377\316"
"\345\376\377\\\253\374\377\326\352\376\377\364\370\376\377D\240\376\377\1"
"\220\377\377\0\203\376\377\265\333\377\377\267\333\377\377\234\314\376\377"
"5\231\377\361\13\204\377\26\5\201\377\\|\274\376\377\315\346\377\377\347"
"\363\377\377p\266\376\377\0~\376\377\20\206\376\377\276\336\376\377\336\356"
"\376\377L\244\376\377\266\332\376\377\376\376\376\377\376\376\376\377\204"
"\267\354\377\0U\226\377\0V\230\377\0V\230\377\1U\217\377\7o\317\377\372\373"
"\376\377\376\376\376\377\273\334\375\377N\245\376\377\330\353\376\377\263"
"\330\375\377\0\203\376\377\0\217\376\377b\257\376\377\317\347\377\377\244"
"\320\376\377j\263\376\377\11\203\377\\\17\206\377\227\225\311\377\377\314"
"\345\376\377\325\352\377\377-\225\377\377\0\203\376\377\\\253\374\377\376"
"\376\376\377\242\315\376\377{\273\375\377\376\376\376\377\376\376\376\377"
"\376\376\376\377\366\371\376\377\7o\317\377\2`\260\377\7i\305\377\1c\257"
"\377\201\270\361\377\376\376\376\377\376\376\376\377\376\376\376\377y\272"
"\375\377{\273\375\377\352\364\376\377F\241\376\377\0\211\376\377\35\215\377"
"\377\315\346\377\377\261\330\377\377\207\302\377\377\17\206\377\227%\221"
"\377\303\242\317\376\377\325\352\377\377\253\323\377\377\16\205\376\377\0"
"~\376\377\224\310\376\377\360\366\376\377_\255\375\377\334\355\376\377\376"
"\376\376\377\376\376\376\377\376\376\376\377\376\376\376\377\344\360\376"
"\377\352\364\376\377\376\376\376\377\312\344\376\377\376\376\376\377\376"
"\376\376\377\376\376\376\377\376\376\376\377\334\355\376\377L\244\376\377"
"\330\353\376\377\221\306\375\377\0\211\376\377\3\200\377\377\252\324\376"
"\377\312\344\376\377\233\314\377\377)\223\377\303;\234\377\330\265\332\377"
"\377\340\360\376\377\221\307\377\377\0~\376\377\20\206\376\377\270\333\376"
"\377\305\341\375\377F\241\376\377\376\376\376\377\376\376\376\377\376\376"
"\376\377\376\376\376\377\376\376\376\377\376\376\376\377\346\361\376\377"
"\310\343\376\377\376\376\376\377\376\376\376\377\376\376\376\377\376\376"
"\376\377\376\376\376\377\376\376\376\377F\241\376\377\270\333\376\377\264"
"\331\376\377\12\203\376\377\1\204\377\377\217\306\377\377\325\352\377\377"
"\255\326\377\377=\235\377\330K\244\377\346\315\347\377\377\351\364\377\377"
"\207\302\377\377\0~\376\377$\217\374\377\334\355\376\377\324\351\376\377"
"\230\312\376\377\376\376\376\377\376\376\376\377\376\376\376\377\376\376"
"\376\377\376\376\376\377\305\341\375\377\1c\257\377\0U\226\377+\221\371\377"
"\372\373\376\377\376\376\376\377\376\376\376\377\376\376\376\377\376\376"
"\376\377\226\311\376\377\314\345\376\377\330\353\376\377\34\213\374\377\1"
"\204\377\377\201\277\377\377\337\360\377\377\272\334\376\377E\241\377\346"
"M\245\377\346\335\356\377\377\363\371\377\377\211\303\377\377\14\204\376"
"\377&\220\374\377\214\303\374\377\241\316\375\377\210\271\354\377\205\267"
"\353\377\204\267\354\377\204\267\354\377\214\276\362\377\376\376\376\377"
"\210\271\354\377\1R\213\377\1R\213\377\2`\260\377\372\374\376\377\334\355"
"\376\377\204\267\354\377\204\267\354\377\205\267\353\377\210\271\354\377"
"\224\310\376\377{\273\375\377\16\205\376\377\1\204\377\377\201\277\377\377"
"\333\356\377\377\272\334\376\377I\243\377\346E\241\377\330\335\355\377\377"
"\373\375\377\377\233\314\377\377\35\215\377\377'\220\373\377\34\213\374\377"
"\20\206\376\377\4h\274\377\1R\213\377\0T\224\377\3N\207\377\1c\257\377\354"
"\364\376\377\370\372\376\377\7i\305\377\1T\241\377d\250\356\377\376\376\376"
"\377M\233\353\377\0U\220\377\0U\220\377\1R\213\377\2b\264\377\0\203\376\377"
"\0~\376\377\10\202\376\377\1\177\377\377\217\306\377\377\327\354\377\377"
"\257\327\377\377=\235\377\330-\225\377\303\315\346\377\377\375\375\377\377"
"\267\333\377\377'\222\377\377&\220\374\377+\221\371\377$\217\374\377\6v\336"
"\377\0P\232\377\1T\241\377\1S\237\377\0U\226\377d\242\342\377\376\376\376"
"\377\372\373\376\377\356\365\376\377\376\376\376\377\336\355\376\377\7i\305"
"\377\0V\230\377\1T\241\377\0P\232\377\6r\326\377\14\204\376\377\16\205\376"
"\377\10\202\376\377\15\205\377\377\252\324\376\377\324\352\376\377\244\320"
"\376\377)\223\377\303\17\206\377\227\263\331\377\377\365\372\377\377\341"
"\360\377\3777\232\377\377\27\211\375\377\40\215\374\377\34\213\374\377\6"
"\201\376\377\1V\245\377\0P\232\377\1T\241\377\0P\232\377\1^\255\377\255\323"
"\375\377\376\376\376\377\376\376\376\377\376\376\376\377+\221\371\377\1U"
"\217\377\1T\241\377\0P\232\377\1V\245\377\1~\375\377\12\203\376\377\16\205"
"\376\377\4\200\376\377'\222\377\377\324\351\376\377\307\343\377\377\223\310"
"\377\377\17\206\377\227\1\177\377\\\207\302\377\377\343\361\377\377\355\366"
"\377\377n\265\376\377\0~\376\377\22\207\376\377\6\201\376\377\4\200\376\377"
"\6p\322\377\0P\232\377\1S\237\377\0U\220\377\7o\317\377\370\372\376\377\376"
"\376\376\377\376\376\376\377\376\376\376\377\255\323\375\377\0S\232\377\0"
"P\232\377\0P\232\377\7o\317\377\4\200\376\377\4\200\376\377\10\202\376\377"
"\1\204\377\377d\260\376\377\333\355\377\377\274\335\376\377x\272\376\377"
"\5\201\377\\\13\204\377\26?\236\377\361\307\343\377\377\333\356\377\377\276"
"\336\376\377\1\177\377\377\0\203\376\377\0~\376\377\4\200\376\377\4\200\376"
"\377\5k\313\377\1U\217\377\1c\257\377\370\372\376\377\376\376\376\377\376"
"\376\376\377\376\376\376\377\376\376\376\377\376\376\376\377d\245\350\377"
"\0U\226\377\5k\313\377\4\200\376\377\0~\376\377\0~\376\377\0\203\376\377"
"\1\204\377\377\274\335\376\377\307\343\377\377\255\326\377\377;\234\377\361"
"\13\204\377\26\0\0\0\0\17\206\377\242\211\303\377\377\265\332\377\377\331"
"\354\377\377U\251\377\377\0\211\376\377\0~\376\377\0~\376\377\4\200\376\377"
"\4\200\376\377\4j\300\377c\246\353\377\346\361\376\377\376\376\376\377\376"
"\376\376\377\376\376\376\377\376\376\376\377\342\357\376\377\302\340\376"
"\377\6v\336\377\0\203\376\377\4\200\376\377\4\200\376\377\0~\376\377\0\216"
"\374\377Q\247\377\377\327\353\377\377\250\322\376\377\207\302\377\377\25"
"\211\377\242\0\0\0\0\0\0\0\0\5\201\377+1\227\377\372\242\317\376\377\253"
"\325\377\377\332\355\376\377%\221\377\377\0\211\376\377\0~\376\377\4\200"
"\376\377\0~\376\377_\255\375\377\340\356\376\377a\256\375\377\\\253\374\377"
"l\264\376\377j\263\376\377c\257\375\377F\241\376\377\276\336\376\377\322"
"\347\376\377\14\204\376\377\0~\376\377\0~\376\377\1\212\377\377%\221\377"
"\377\325\352\377\377\240\316\376\377\240\316\376\377;\234\377\372\13\204"
"\377+\0\0\0\0\0\0\0\0\0\0\0\0\7\202\377\213f\261\376\377\252\324\376\377"
"\314\345\376\377\307\343\377\377\21\213\375\377\0\211\376\377\4\200\376\377"
"\0~\376\377\223\307\375\377\376\376\376\377\354\364\376\377\324\350\376\377"
"\321\347\375\377\322\347\376\377\321\347\375\377\356\365\376\377\372\374"
"\376\377\264\331\376\377\34\213\374\377\1~\375\377\1\212\377\377\17\213\377"
"\377\312\344\376\377\312\344\376\377\236\315\376\377n\265\376\377\15\205"
"\377\213\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1g\377\5\23\210\377\322|\274\376"
"\377\234\314\376\377\303\341\377\377\315\345\377\3777\231\375\377\0\211\376"
"\377\4\200\376\377\34\213\374\377N\245\376\377\223\307\375\377\270\333\376"
"\377\322\350\376\377\322\350\376\377\270\333\376\377\223\307\375\377N\245"
"\376\377\10\202\376\377\0~\376\377\1\212\377\377;\240\377\377\314\345\376"
"\377\307\343\377\377\240\316\376\377\207\302\377\377\33\214\377\322\1g\377"
"\5\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\13\204\377,\37\216\377\360\215"
"\305\377\377\240\316\376\377\317\347\377\377\335\354\377\377a\256\375\377"
"\10\202\376\377\0~\376\377\0\203\376\377\0~\376\377\27\211\375\377'\220\373"
"\377+\221\371\377\27\211\375\377\0~\376\377\0\211\376\377\1\204\377\377\1"
"\177\377\377`\256\376\377\337\356\377\377\321\350\377\377\242\317\376\377"
"\231\313\377\377)\223\377\360\13\204\377,\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\13\204\377/#\220\377\350\205\301\377\377\265\332"
"\377\377\300\337\376\377\351\363\377\377\301\340\377\377t\270\376\3775\231"
"\377\377\23\210\377\377\14\204\376\377\10\202\376\377\10\202\376\377\14\204"
"\376\377\22\207\376\3771\227\377\377p\266\376\377\272\334\376\377\341\357"
"\377\377\274\335\376\377\272\334\376\377\221\307\377\377'\222\377\350\13"
"\204\377/\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\13\204\3772\27\212\377\320z\273\376\377\305\342\377\377\315\346"
"\377\377\343\361\377\377\347\364\377\377\327\353\377\377\263\327\377\377"
"\236\315\376\377\213\304\377\377\215\305\377\377\240\316\376\377\263\331"
"\377\377\327\353\377\377\343\361\377\377\325\352\377\377\267\333\377\377"
"\274\335\376\377\201\277\377\377\33\214\377\320\13\204\3772\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\1s\377\7\11\203\377\214?\236\377\371\231\313\377\377\307\343\377\377\321"
"\350\377\377\321\350\377\377\335\357\377\377\347\363\377\377\363\371\377"
"\377\367\373\377\377\351\364\377\377\333\355\377\377\315\346\377\377\314"
"\345\376\377\276\336\376\377\225\311\377\377A\237\377\371\13\204\377\214"
"\1s\377\7\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\5\201\3772\21\207\377\240"
"=\235\377\351~\275\376\377\233\314\377\377\257\327\377\377\307\343\377\377"
"\333\355\377\377\335\355\377\377\312\344\376\377\257\327\377\377\227\312"
"\377\377|\274\376\377A\237\377\351\25\211\377\240\5\201\3772\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\11}\377\33\3"
"\200\377]\15\205\377\225'\222\377\301?\236\377\330K\244\377\346K\244\377"
"\346?\236\377\330+\224\377\301\17\206\377\225\3\200\377]\11}\377\33\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0",
#if 0
};
#endif

View file

@ -0,0 +1,434 @@
/* GIMP RGBA C-Source image dump (eduke32_icon_48px.c) */
#if 0
static const struct {
unsigned int width;
unsigned int height;
unsigned int bytes_per_pixel; /* 3:RGB, 4:RGBA */
unsigned char pixel_data[48 * 48 * 4 + 1];
} sdlappicon = {
48, 48, 4,
#endif
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\1\377\1\31\213"
"\377(\31\213\377_\31\213\377\222\31\213\377\270\31\213\377\321\31\213\377"
"\343\31\213\377\355\31\213\377\355\31\213\377\343\31\213\377\321\31\213\377"
"\270\31\213\377\222\31\213\377_\31\213\377(\1\1\377\1\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\31\213\377\36\31\213\377s\31\213\377\304\31\213\377\365?\236\377\377"
"f\261\376\377\205\301\377\377\246\321\376\377\303\341\377\377\305\342\377"
"\377\301\340\377\377\253\325\377\377\207\302\377\377h\262\376\377M\245\377"
"\3771\227\377\377\31\213\377\365\31\213\377\304\31\213\377s\31\213\377\36"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\33\221\377"
"&\31\213\377\222\31\213\377\354E\241\377\377\234\314\376\377\341\357\377"
"\377\367\373\377\377\375\376\377\377\375\376\377\377\371\374\377\377\357"
"\367\377\377\343\361\377\377\335\355\377\377\321\350\377\377\300\337\376"
"\377\272\334\376\377\272\334\376\377\255\326\377\377\240\316\376\377t\270"
"\376\3775\231\377\377\31\213\377\354\31\213\377\222\33\221\377&\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\25\203\377\14\31\213\377|\31\213\377\354Q\247\377"
"\377\274\335\376\377\353\365\377\377\365\372\377\377\365\372\377\377\371"
"\374\377\377\363\371\377\377\365\372\377\377\365\372\377\377\353\365\377"
"\377\341\357\377\377\332\354\376\377\315\346\377\377\274\335\376\377\265"
"\332\377\377\257\327\377\377\250\322\376\377\246\321\376\377\252\324\376"
"\377\265\332\377\377\242\317\376\377K\244\377\377\31\213\377\354\31\213\377"
"|\25\203\377\14\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\31\213\3774\31\213\377\3055\231\377\377\236\315\376"
"\377\314\345\376\377\327\353\377\377\341\357\377\377\353\365\377\377\361"
"\370\377\377\367\373\377\377\371\374\377\377\371\374\377\377\373\375\377"
"\377\371\374\377\377\371\374\377\377\367\373\377\377\357\367\377\377\343"
"\361\377\377\325\352\377\377\274\335\376\377\244\320\376\377\244\320\376"
"\377\250\322\376\377\265\332\377\377\305\342\377\377\314\345\376\377\257"
"\327\377\377;\234\377\377\31\213\377\305\31\213\3774\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377Z\31\213\377\356K"
"\244\377\377\244\320\376\377\263\331\377\377\276\336\376\377\314\345\376"
"\377\332\354\376\377\353\365\377\377\367\373\377\377\375\376\377\377\335"
"\355\377\377\253\325\377\377\211\303\377\377p\266\376\377Z\253\376\377S\250"
"\377\377^\255\376\377t\270\376\377\234\314\376\377\327\353\377\377\365\372"
"\377\377\327\353\377\377\274\335\376\377\300\337\376\377\305\342\377\377"
"\312\344\376\377\325\352\377\377\343\361\377\377l\264\376\377\31\213\377"
"\356\31\213\377Z\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377"
"q\31\213\377\374^\255\376\377\225\311\377\377\231\313\377\377\246\321\376"
"\377\267\333\377\377\327\353\377\377\363\371\377\377\325\352\377\377\217"
"\306\377\377Q\247\377\377;\234\377\377;\234\377\377;\234\377\3775\231\377"
"\377/\226\377\377'\222\377\377\35\215\377\377\23\210\377\377\21\207\377\377"
"\15\205\377\377%\221\377\377x\272\376\377\317\347\377\377\357\367\377\377"
"\332\354\376\377\317\347\377\377\333\355\377\377\351\364\377\377\355\366"
"\377\377\227\312\377\377\31\213\377\374\31\213\377q\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\31\213\377q\23\210\377\377^\255\376\377\211\303\377\377\211\303"
"\377\377\221\307\377\377\250\322\376\377\333\355\377\377\324\351\376\377"
"`\256\376\377+\224\377\3771\227\377\3779\233\377\377;\234\377\377;\234\377"
"\377;\234\377\3779\233\377\377/\226\377\377)\223\377\377\33\214\377\377\23"
"\210\377\377\21\207\377\377\11\203\377\377\7\202\377\377\13\204\377\377\27"
"\212\377\377^\255\376\377\325\352\377\377\357\367\377\377\345\362\377\377"
"\353\365\377\377\351\364\377\377\355\366\377\377\257\327\377\377\37\216\377"
"\377\31\213\377q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377Z\31\213\377\374Z\253\376\377"
"~\275\376\377|\274\376\377\203\300\377\377\257\327\377\377\373\375\377\377"
"x\272\376\377\17\206\377\377\33\214\377\377%\221\377\377/\226\377\3777\232"
"\377\377;\234\377\377;\234\377\377;\234\377\3779\233\377\3771\227\377\377"
")\223\377\377\33\214\377\377\23\210\377\377\17\206\377\377\11\203\377\377"
"\7\202\377\377\17\206\377\377\31\213\377\377\35\215\377\377#\220\377\377"
"\215\305\377\377\375\376\377\377\357\367\377\377\351\364\377\377\343\361"
"\377\377\341\357\377\377\244\320\376\377\31\213\377\374\31\213\377Z\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\33\214"
"\3771\31\213\377\355Q\247\377\377\200\276\376\377t\270\376\377x\272\376\377"
"\267\333\377\377\353\365\377\377?\236\377\377\1\177\377\377\11\203\377\377"
"\23\210\377\377!\217\377\377+\224\377\3773\230\377\3779\233\377\377;\234"
"\377\377;\234\377\3779\233\377\3771\227\377\377'\222\377\377\33\214\377\377"
"\23\210\377\377\15\205\377\377\7\202\377\377\11\203\377\377\25\211\377\377"
"\35\215\377\377\37\216\377\377+\224\377\3771\227\377\377l\264\376\377\361"
"\370\377\377\357\367\377\377\333\355\377\377\317\347\377\377\314\345\376"
"\377\201\277\377\377\31\213\377\355\33\214\3771\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\27\217\377\13\31\213\377\310=\235\377\377"
"\217\306\377\377\203\300\377\377~\275\376\377\267\333\377\377\332\354\376"
"\377\25\211\377\377\0w\360\377\0{\370\377\1\177\377\377\13\204\377\377\33"
"\214\377\377'\222\377\3771\227\377\3779\233\377\377;\234\377\377;\234\377"
"\3779\233\377\3771\227\377\377'\222\377\377\33\214\377\377\21\207\377\377"
"\15\205\377\377\7\202\377\377\15\205\377\377\31\213\377\377\35\215\377\377"
"%\221\377\3771\227\377\3773\230\377\3773\230\377\377M\245\377\377\341\357"
"\377\377\345\362\377\377\301\340\377\377\274\335\376\377\303\341\377\377"
"U\251\377\377\31\213\377\310\27\217\377\13\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\31\213\377|#\220\377\377\231\313\377\377\225\311\377\377"
"\213\304\377\377\265\332\377\377\343\361\377\377\11\203\377\377\0u\354\377"
"\0v\356\377\0x\362\377\0|\372\377+\224\377\377\257\327\377\3771\227\377\377"
"-\225\377\3775\231\377\377;\234\377\377;\234\377\377;\234\377\3771\227\377"
"\377'\222\377\377\27\212\377\377\21\207\377\377\13\204\377\377\11\203\377"
"\377\23\210\377\377\35\215\377\377x\272\376\377O\246\377\3773\230\377\377"
"3\230\377\377/\226\377\377+\224\377\3779\233\377\377\347\363\377\377\325"
"\352\377\377\267\333\377\377\267\333\377\377\257\327\377\377'\222\377\377"
"\31\213\377|\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\27\212\377\"\31\213"
"\377\356\203\300\377\377\250\322\376\377\234\314\376\377\246\321\376\377"
"\371\374\377\377+\224\377\377\0u\354\377\0t\352\377\0t\352\377\0v\356\377"
"A\237\377\377\363\371\377\377\325\352\377\377\242\317\376\377'\222\377\377"
"\35\215\377\377\1\177\377\377\0o\340\377\0b\306\377\0Y\264\377\0Y\264\377"
"\0_\300\377\0g\320\377\0p\342\377\0}\374\377\27\212\377\377=\235\377\377"
"\373\375\377\377\365\372\377\377n\265\376\3771\227\377\377+\224\377\377!"
"\217\377\377\31\213\377\377E\241\377\377\371\374\377\377\276\336\376\377"
"\253\325\377\377\244\320\376\377\207\302\377\377\31\213\377\356\27\212\377"
"\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377\222;\234\377\377\272\334\376"
"\377\253\325\377\377\250\322\376\377\327\353\377\377p\266\376\377\0|\372"
"\377\0y\364\377\0w\360\377\0t\352\377X\252\376\377\373\375\377\377\253\325"
"\377\377\231\313\377\377\371\374\377\377\17\206\377\377\0V\256\377\0T\252"
"\377\0R\246\377\0P\242\377\0O\240\377\0O\240\377\0P\242\377\0R\246\377\0"
"T\252\377\0V\256\377\0q\344\377\255\326\377\377\361\370\377\377\361\370\377"
"\377\375\376\377\377~\275\376\377!\217\377\377\33\214\377\377\27\212\377"
"\377\21\207\377\377x\272\376\377\332\354\376\377\236\315\376\377\234\314"
"\376\377\240\316\376\3779\233\377\377\31\213\377\222\0\0\0\0\0\0\0\0\0\0"
"\0\0\31\213\377\36\31\213\377\355\234\314\376\377\301\340\377\377\265\332"
"\377\377\314\345\376\377\321\350\377\377\11\203\377\377\3\200\377\377\1\177"
"\377\377\0z\366\377A\237\377\377\373\375\377\377\223\310\377\377\200\276"
"\376\377j\263\376\377\217\306\377\377\234\314\376\377\0P\242\377\0O\240\377"
"\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240"
"\377\0P\242\377\0s\350\377\333\355\377\377\255\326\377\377\347\363\377\377"
"\341\357\377\377\375\376\377\377^\255\376\377\27\212\377\377\21\207\377\377"
"\11\203\377\377\7\202\377\377\317\347\377\377\272\334\376\377\223\310\377"
"\377\225\311\377\377\203\300\377\377\31\213\377\355\31\213\377\36\0\0\0\0"
"\0\0\0\0\31\213\377q3\230\377\377\315\346\377\377\305\342\377\377\300\337"
"\376\377\355\366\377\377S\250\377\377\17\206\377\377\13\204\377\377\7\202"
"\377\377+\224\377\377\357\367\377\377\250\322\376\377x\272\376\377U\251\377"
"\377S\250\377\377\274\335\376\377\377\377\377\377\7\202\377\377\0O\240\377"
"\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240"
"\377\0O\240\377\236\315\376\377\325\352\377\377S\250\377\377\225\311\377"
"\377\305\342\377\377\317\347\377\377\361\370\377\3773\230\377\377\7\202\377"
"\377\3\200\377\377\1\177\377\377E\241\377\377\343\361\377\377\225\311\377"
"\377\227\312\377\377\240\316\376\377-\225\377\377\31\213\377q\0\0\0\0\1["
"\377\3\31\213\377\305z\273\376\377\305\342\377\377\276\336\376\377\315\346"
"\377\377\321\350\377\377\31\213\377\377\27\212\377\377\25\211\377\377\21"
"\207\377\377\267\333\377\377\312\344\376\377\223\310\377\377f\261\376\377"
"S\250\377\377\314\345\376\377\377\377\377\377\377\377\377\377\315\346\377"
"\377\0S\250\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0"
"O\240\377\0O\240\377\0|\372\377\377\377\377\377\377\377\377\377\314\345\376"
"\377S\250\377\377\215\305\377\377\265\332\377\377\317\347\377\377\267\333"
"\377\377\3\200\377\377\1\177\377\377\0}\374\377\0}\374\377\314\345\376\377"
"\255\326\377\377\231\313\377\377\236\315\376\377h\262\376\377\31\213\377"
"\305\1[\377\3\33\214\377'\31\213\377\366\255\326\377\377\272\334\376\377"
"\274\335\376\377\345\362\377\377v\271\376\377\33\214\377\377\33\214\377\377"
"\33\214\377\377Q\247\377\377\355\366\377\377\261\330\377\377\223\310\377"
"\3777\232\377\377\274\335\376\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377E\241\377\377\0O\240\377\0O\240\377\0O\240\377\0"
"O\240\377\0O\240\377\0O\240\377\0O\240\377\272\334\376\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\274\335\376\3777\232\377\377\221\307\377"
"\377\234\314\376\377\345\362\377\377?\236\377\377\1\177\377\377\1\177\377"
"\377\3\200\377\377h\262\376\377\325\352\377\377\227\312\377\377\227\312\377"
"\377\223\310\377\377\31\213\377\366\33\214\377'\31\213\377_3\230\377\377"
"\272\334\376\377\267\333\377\377\267\333\377\377\375\376\377\377%\221\377"
"\377\27\212\377\377\27\212\377\377\33\214\377\377\303\341\377\377\325\352"
"\377\377\276\336\376\377j\263\376\377\215\305\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\357\367\377"
"\377\0b\306\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\25"
"\211\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\215\305\377\377X\252\376\377\227\312\377\377\274\335"
"\376\377\276\336\376\377\1\177\377\377\1\177\377\377\1\177\377\377\21\207"
"\377\377\373\375\377\377\236\315\376\377\236\315\376\377\246\321\376\377"
"/\226\377\377\31\213\377_\31\213\377\222K\244\377\377\272\334\376\377\263"
"\331\377\377\303\341\377\377\312\344\376\377\23\210\377\377\23\210\377\377"
"\23\210\377\3771\227\377\377\375\376\377\377\300\337\376\377\246\321\376"
"\377A\237\377\377\340\360\376\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\203\300\377\377"
"\0l\332\377X\252\376\377t\270\376\377)\223\377\377\0]\274\377\315\346\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\340\360\376\377A\237\377\377\205\301\377\377\231\313\377\377"
"\373\375\377\377\35\215\377\377\1\177\377\377\3\200\377\377\5\201\377\377"
"\307\343\377\377\267\333\377\377\244\320\376\377\255\326\377\377G\242\377"
"\377\31\213\377\222\31\213\377\272j\263\376\377\267\333\377\377\261\330\377"
"\377\325\352\377\377\225\311\377\377\23\210\377\377\23\210\377\377\23\210"
"\377\377l\264\376\377\343\361\377\377\267\333\377\377t\270\376\377~\275\376"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377~\275\376\377b\257\376\377\236\315\376"
"\377\333\355\377\377f\261\376\377\7\202\377\377\7\202\377\377\11\203\377"
"\377\223\310\377\377\315\346\377\377\246\321\376\377\252\324\376\377n\265"
"\376\377\31\213\377\272\31\213\377\321\207\302\377\377\274\335\376\377\265"
"\332\377\377\343\361\377\377r\267\376\377\23\210\377\377\21\207\377\377\21"
"\207\377\377\234\314\376\377\324\351\376\377\261\330\377\377M\245\377\377"
"\261\330\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\261\330\377\377I\243\377"
"\377\244\320\376\377\314\345\376\377\227\312\377\377\11\203\377\377\11\203"
"\377\377\11\203\377\377n\265\376\377\335\355\377\377\252\324\376\377\255"
"\326\377\377\213\304\377\377\31\213\377\321\31\213\377\343\246\321\376\377"
"\274\335\376\377\267\333\377\377\353\365\377\377Z\253\376\377\25\211\377"
"\377\23\210\377\377\23\210\377\377\276\336\376\377\312\344\376\377\263\331"
"\377\3773\230\377\377\332\354\376\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\261\330\377\377\0n\336\377\0O\240\377\3\200\377\377"
"\325\352\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\332\354\376\377"
"1\227\377\377\252\324\376\377\300\337\376\377\301\340\377\377\15\205\377"
"\377\15\205\377\377\15\205\377\377U\251\377\377\347\363\377\377\255\326\377"
"\377\257\327\377\377\227\312\377\377\31\213\377\343\31\213\377\355\267\333"
"\377\377\307\343\377\377\301\340\377\377\361\370\377\377Q\247\377\377\33"
"\214\377\377\33\214\377\377\33\214\377\377\317\347\377\377\315\346\377\377"
"\314\345\376\377M\245\377\377\367\373\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\373\375\377\377\0b\306\377\0O\240\377\0O\240\377\0O\240\377"
"\1\177\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\367\373\377\377K\244"
"\377\377\300\337\376\377\300\337\376\377\315\346\377\377\17\206\377\377\17"
"\206\377\377\17\206\377\377G\242\377\377\355\366\377\377\257\327\377\377"
"\261\330\377\377\250\322\376\377\31\213\377\355\31\213\377\355\274\335\376"
"\377\315\346\377\377\314\345\376\377\363\371\377\377U\251\377\377!\217\377"
"\377!\217\377\377!\217\377\377\257\327\377\377\324\351\376\377\324\351\376"
"\377\276\336\376\377\272\334\376\377\272\334\376\377\272\334\376\377\272"
"\334\376\377\272\334\376\377\272\334\376\377\343\361\377\377\377\377\377"
"\377\312\344\376\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0W\260\377"
"\377\377\377\377\377\377\377\377\325\352\377\377\272\334\376\377\272\334"
"\376\377\272\334\376\377\272\334\376\377\272\334\376\377\276\336\376\377"
"\317\347\377\377\317\347\377\377\250\322\376\377\15\205\377\377\15\205\377"
"\377\15\205\377\377E\241\377\377\353\365\377\377\255\326\377\377\257\327"
"\377\377\250\322\376\377\31\213\377\355\31\213\377\343\274\335\376\377\325"
"\352\377\377\321\350\377\377\361\370\377\377f\261\376\377%\221\377\377'\222"
"\377\377'\222\377\377'\222\377\377'\222\377\377'\222\377\377\0a\304\377\0"
"P\242\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377S\250\377"
"\377\377\377\377\377\363\371\377\377\0[\270\377\0O\240\377\0O\240\377\0O"
"\240\377\0t\352\377\377\377\377\377\377\377\377\377\25\211\377\377\0O\240"
"\377\0O\240\377\0O\240\377\0O\240\377\0P\242\377\0^\276\377\15\205\377\377"
"\15\205\377\377\15\205\377\377\15\205\377\377\15\205\377\377\15\205\377\377"
"U\251\377\377\347\363\377\377\255\326\377\377\255\326\377\377\240\316\376"
"\377\31\213\377\343\31\213\377\321\246\321\376\377\333\355\377\377\327\353"
"\377\377\357\367\377\377~\275\376\377'\222\377\377+\224\377\377+\224\377"
"\377+\224\377\377+\224\377\377)\223\377\377\0l\332\377\0R\246\377\0O\240"
"\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\35\215\377\377\377\377\377"
"\377\377\377\377\377\231\313\377\377\0[\270\377\0O\240\377\0h\322\377\305"
"\342\377\377\377\377\377\377\377\377\377\377\0h\322\377\0O\240\377\0O\240"
"\377\0O\240\377\0O\240\377\0R\246\377\0g\320\377\17\206\377\377\17\206\377"
"\377\15\205\377\377\15\205\377\377\15\205\377\377\15\205\377\377n\265\376"
"\377\340\356\376\377\255\326\377\377\261\330\377\377\213\304\377\377\31\213"
"\377\321\31\213\377\272\203\300\377\377\340\356\376\377\333\355\377\377\351"
"\364\377\377\240\316\376\377)\223\377\377+\224\377\377)\223\377\377)\223"
"\377\377%\221\377\377%\221\377\377\0w\360\377\0T\252\377\0O\240\377\0O\240"
"\377\0O\240\377\0O\240\377\0O\240\377\0U\254\377\315\346\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\347\363\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\236\315\376\377\0O\240\377\0O\240\377\0"
"O\240\377\0O\240\377\0O\240\377\0T\252\377\0r\346\377\15\205\377\377\15\205"
"\377\377\15\205\377\377\15\205\377\377\15\205\377\377\17\206\377\377\223"
"\310\377\377\324\351\376\377\257\327\377\377\263\331\377\377r\267\376\377"
"\31\213\377\272\31\213\377\222^\255\376\377\340\356\376\377\333\355\377\377"
"\341\357\377\377\315\346\377\377'\222\377\377%\221\377\377%\221\377\377!"
"\217\377\377\37\216\377\377\35\215\377\377\11\203\377\377\0V\256\377\0P\242"
"\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0j\326\377\312"
"\344\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\242\317\376\377\0]\274\377\0O\240\377\0O\240\377\0O"
"\240\377\0O\240\377\0P\242\377\0V\256\377\0|\372\377\13\204\377\377\13\204"
"\377\377\15\205\377\377\15\205\377\377\15\205\377\377\15\205\377\377\307"
"\343\377\377\301\340\377\377\261\330\377\377\265\332\377\377M\245\377\377"
"\31\213\377\222\31\213\377_9\233\377\377\335\355\377\377\327\353\377\377"
"\324\351\376\377\375\376\377\3773\230\377\377!\217\377\377\35\215\377\377"
"\33\214\377\377\33\214\377\377\25\211\377\377\17\206\377\377\0m\334\377\0"
"S\250\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377"
"p\266\376\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377)\223\377\377\0O\240\377\0O\240\377\0O\240\377\0O\240"
"\377\0O\240\377\0S\250\377\0l\332\377\5\201\377\377\7\202\377\377\11\203"
"\377\377\15\205\377\377\15\205\377\377\15\205\377\377\37\216\377\377\375"
"\376\377\377\257\327\377\377\257\327\377\377\265\332\377\3771\227\377\377"
"\31\213\377_\33\214\377'\31\213\377\366\303\341\377\377\315\346\377\377\312"
"\344\376\377\351\364\377\377v\271\376\377\33\214\377\377\27\212\377\377\25"
"\211\377\377\17\206\377\377\7\202\377\377\3\200\377\377\0z\366\377\0V\256"
"\377\0Q\244\377\0O\240\377\0O\240\377\0O\240\377\0O\240\377\0t\352\377\373"
"\375\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\347\363\377\377\0[\270\377\0O\240\377\0O\240\377\0O"
"\240\377\0Q\244\377\0V\256\377\0x\362\377\1\177\377\377\3\200\377\377\5\201"
"\377\377\7\202\377\377\11\203\377\377\11\203\377\377j\263\376\377\340\356"
"\376\377\253\325\377\377\255\326\377\377\252\324\376\377\31\213\377\366\33"
"\214\377'\1[\377\3\31\213\377\305\201\277\377\377\314\345\376\377\305\342"
"\377\377\317\347\377\377\315\346\377\377\23\210\377\377\15\205\377\377\11"
"\203\377\377\5\201\377\377\1\177\377\377\1\177\377\377\3\200\377\377\0t\352"
"\377\0U\254\377\0Q\244\377\0O\240\377\0O\240\377\0Q\244\377\276\336\376\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\203\300\377\377\0O\240\377\0O\240"
"\377\0Q\244\377\0U\254\377\0s\350\377\0|\372\377\0|\372\377\0}\374\377\1"
"\177\377\377\3\200\377\377\7\202\377\377\11\203\377\377\314\345\376\377\272"
"\334\376\377\250\322\376\377\255\326\377\377t\270\376\377\31\213\377\305"
"\1[\377\3\0\0\0\0\31\213\377q1\227\377\377\312\344\376\377\274\335\376\377"
"\263\331\377\377\351\364\377\377K\244\377\377\5\201\377\377\1\177\377\377"
"\1\177\377\377\1\177\377\377\1\177\377\377\1\177\377\377\1\177\377\377\0"
"p\342\377\0U\254\377\0Q\244\377\0O\240\377E\241\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\0|\372\377\0Q\244\377"
"\0U\254\377\0q\344\377\1\177\377\377\1\177\377\377\0}\374\377\0}\374\377"
"\0|\372\377\1\177\377\377\1\177\377\377E\241\377\377\347\363\377\377\244"
"\320\376\377\250\322\376\377\257\327\377\377/\226\377\377\31\213\377q\0\0"
"\0\0\0\0\0\0\31\213\377\36\31\213\377\355\221\307\377\377\263\331\377\377"
"\252\324\376\377\276\336\376\377\317\347\377\377\3\200\377\377\1\177\377"
"\377\1\177\377\377\1\177\377\377\1\177\377\377\1\177\377\377\0}\374\377\1"
"\177\377\377\0u\354\377\0V\256\377\0k\330\377\357\367\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377\377"
"\377\377\377\377\377\377\377\377\377\377\377\351\364\377\377\317\347\377"
"\377\0Z\266\377\0v\356\377\3\200\377\377\1\177\377\377\3\200\377\377\1\177"
"\377\377\0}\374\377\0|\372\377\0|\372\377\1\177\377\377\317\347\377\377\274"
"\335\376\377\234\314\376\377\246\321\376\377\217\306\377\377\31\213\377\355"
"\31\213\377\36\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377\2221\227\377\377\252\324"
"\376\377\234\314\376\377\231\313\377\377\325\352\377\377r\267\376\377\1\177"
"\377\377\1\177\377\377\1\177\377\377\0}\374\377\0}\374\377\1\177\377\377"
"\7\202\377\377\11\203\377\377\3\200\377\377\257\327\377\377\227\312\377\377"
"~\275\376\377\261\330\377\377\332\354\376\377\365\372\377\377\365\372\377"
"\377\332\354\376\377\261\330\377\377~\275\376\377A\237\377\377\274\335\376"
"\377\207\302\377\377\15\205\377\377\11\203\377\377\3\200\377\377\1\177\377"
"\377\1\177\377\377\1\177\377\377\1\177\377\377\0}\374\377n\265\376\377\321"
"\350\377\377\221\307\377\377\227\312\377\377\244\320\376\377?\236\377\377"
"\31\213\377\222\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\27\212\377\"\31\213\377\356"
"x\272\376\377\234\314\376\377\231\313\377\377\253\325\377\377\371\374\377"
"\3771\227\377\377\1\177\377\377\0}\374\377\0}\374\377\1\177\377\377\5\201"
"\377\377\11\203\377\377\15\205\377\377f\261\376\377\351\364\377\377\246\321"
"\376\377x\272\376\377Q\247\377\3775\231\377\377!\217\377\377!\217\377\377"
"5\231\377\377O\246\377\377t\270\376\377\236\315\376\377\265\332\377\377\371"
"\374\377\3775\231\377\377\15\205\377\377\7\202\377\377\1\177\377\377\1\177"
"\377\377\1\177\377\377\1\177\377\3771\227\377\377\371\374\377\377\242\317"
"\376\377\217\306\377\377\225\311\377\377\201\277\377\377\31\213\377\356\27"
"\212\377\"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377|\35\215\377"
"\377\234\314\376\377\236\315\376\377\234\314\376\377\301\340\377\377\343"
"\361\377\377\33\214\377\377\0}\374\377\1\177\377\377\3\200\377\377\7\202"
"\377\377\13\204\377\377\37\216\377\377\353\365\377\377\325\352\377\377\301"
"\340\377\377\274\335\376\377\274\335\376\377\303\341\377\377\314\345\376"
"\377\315\346\377\377\303\341\377\377\272\334\376\377\267\333\377\377\267"
"\333\377\377\315\346\377\377\351\364\377\377\215\305\377\377\15\205\377\377"
"\11\203\377\377\5\201\377\377\1\177\377\377\1\177\377\377\33\214\377\377"
"\345\362\377\377\301\340\377\377\223\310\377\377\223\310\377\377\227\312"
"\377\377+\224\377\377\31\213\377|\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\27\217\377\13\31\213\377\310;\234\377\377\242\317\376\377\227\312"
"\377\377\225\311\377\377\307\343\377\377\333\355\377\377#\220\377\377\3\200"
"\377\377\5\201\377\377\11\203\377\377\15\205\377\377\23\210\377\377U\251"
"\377\377\301\340\377\377\373\375\377\377\347\363\377\377\327\353\377\377"
"\333\355\377\377\327\353\377\377\332\354\376\377\333\355\377\377\327\353"
"\377\377\345\362\377\377\371\374\377\377\300\337\376\377M\245\377\377\11"
"\203\377\377\13\204\377\377\15\205\377\377\13\204\377\377\5\201\377\377#"
"\220\377\377\333\355\377\377\314\345\376\377\231\313\377\377\227\312\377"
"\377\231\313\377\377O\246\377\377\31\213\377\310\27\217\377\13\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\33\214\3771\31\213\377\355"
"\\\254\376\377\231\313\377\377\225\311\377\377\223\310\377\377\305\342\377"
"\377\355\366\377\377E\241\377\377\7\202\377\377\15\205\377\377\21\207\377"
"\377\27\212\377\377\33\214\377\377\33\214\377\377'\222\377\377h\262\376\377"
"\244\320\376\377\255\326\377\377\324\351\376\377\324\351\376\377\255\326"
"\377\377\244\320\376\377h\262\376\377#\220\377\377\23\210\377\377\21\207"
"\377\377\15\205\377\377\13\204\377\377\15\205\377\377\15\205\377\377E\241"
"\377\377\355\366\377\377\305\342\377\377\231\313\377\377\231\313\377\377"
"\236\315\376\377r\267\376\377\31\213\377\355\33\214\3771\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377Z\31\213"
"\377\374r\267\376\377\234\314\376\377\227\312\377\377\234\314\376\377\301"
"\340\377\377\375\376\377\377~\275\376\377\17\206\377\377\23\210\377\377\27"
"\212\377\377\31\213\377\377\31\213\377\377\27\212\377\377\25\211\377\377"
"\31\213\377\377\35\215\377\377!\217\377\377#\220\377\377\35\215\377\377\27"
"\212\377\377\23\210\377\377\23\210\377\377\23\210\377\377\23\210\377\377"
"\17\206\377\377\13\204\377\377\13\204\377\377~\275\376\377\375\376\377\377"
"\303\341\377\377\236\315\376\377\231\313\377\377\236\315\376\377\203\300"
"\377\377\31\213\377\374\31\213\377Z\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377q\27\212\377"
"\377v\271\376\377\240\316\376\377\242\317\376\377\244\320\376\377\263\331"
"\377\377\340\356\376\377\324\351\376\377O\246\377\377\33\214\377\377\33\214"
"\377\377\27\212\377\377\27\212\377\377\25\211\377\377\33\214\377\377\35\215"
"\377\377!\217\377\377!\217\377\377\37\216\377\377\31\213\377\377\23\210\377"
"\377\23\210\377\377\23\210\377\377\23\210\377\377\17\206\377\377G\242\377"
"\377\321\350\377\377\335\355\377\377\265\332\377\377\250\322\376\377\252"
"\324\376\377\242\317\376\377\205\301\377\377!\217\377\377\31\213\377q\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\377q\31\213\377\374l\264\376\377\244"
"\320\376\377\253\325\377\377\253\325\377\377\261\330\377\377\317\347\377"
"\377\357\367\377\377\315\346\377\377\201\277\377\3773\230\377\377\25\211"
"\377\377\27\212\377\377\33\214\377\377\37\216\377\377#\220\377\377!\217\377"
"\377\37\216\377\377\33\214\377\377\27\212\377\377\23\210\377\377/\226\377"
"\377~\275\376\377\315\346\377\377\353\365\377\377\307\343\377\377\252\324"
"\376\377\255\326\377\377\255\326\377\377\253\325\377\377z\273\376\377\31"
"\213\377\374\31\213\377q\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\31\213\377Z\31\213\377\356M\245\377\377\257\327\377\377\267\333\377\377"
"\267\333\377\377\274\335\376\377\300\337\376\377\317\347\377\377\343\361"
"\377\377\367\373\377\377\325\352\377\377\244\320\376\377\200\276\376\377"
"x\272\376\377U\251\377\377U\251\377\377z\273\376\377\200\276\376\377\242"
"\317\376\377\325\352\377\377\367\373\377\377\340\356\376\377\307\343\377"
"\377\257\327\377\377\253\325\377\377\252\324\376\377\263\331\377\377\261"
"\330\377\377X\252\376\377\31\213\377\356\31\213\377Z\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\31\213\3774\31\213\377\305-"
"\225\377\377\225\311\377\377\300\337\376\377\303\341\377\377\303\341\377"
"\377\300\337\376\377\276\336\376\377\267\333\377\377\305\342\377\377\327"
"\353\377\377\345\362\377\377\347\363\377\377\363\371\377\377\363\371\377"
"\377\351\364\377\377\345\362\377\377\327\353\377\377\305\342\377\377\272"
"\334\376\377\272\334\376\377\265\332\377\377\267\333\377\377\263\331\377"
"\377\257\327\377\377\225\311\377\3773\230\377\377\31\213\377\305\31\213\377"
"4\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\25\203\377\14\31\213\377|\31\213\377\354A\237\377\377\242\317\376"
"\377\312\344\376\377\303\341\377\377\276\336\376\377\272\334\376\377\272"
"\334\376\377\276\336\376\377\303\341\377\377\305\342\377\377\315\346\377"
"\377\317\347\377\377\314\345\376\377\303\341\377\377\274\335\376\377\272"
"\334\376\377\267\333\377\377\267\333\377\377\276\336\376\377\272\334\376"
"\377\242\317\376\377I\243\377\377\31\213\377\354\31\213\377|\25\203\377\14"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\33\221\377&\31\213\377\222\31\213\377\354"
"-\225\377\377z\273\376\377\261\330\377\377\303\341\377\377\305\342\377\377"
"\303\341\377\377\307\343\377\377\312\344\376\377\321\350\377\377\324\351"
"\376\377\317\347\377\377\312\344\376\377\303\341\377\377\301\340\377\377"
"\274\335\376\377\257\327\377\377\200\276\376\3777\232\377\377\31\213\377"
"\354\31\213\377\222\33\221\377&\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\31\213\377\36\31\213\377s\31\213\377\304\31\213\377"
"\365/\226\377\377M\245\377\377r\267\376\377\223\310\377\377\257\327\377\377"
"\272\334\376\377\272\334\376\377\261\330\377\377\225\311\377\377v\271\376"
"\377S\250\377\3771\227\377\377\31\213\377\365\31\213\377\304\31\213\377s"
"\31\213\377\36\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\1\1\377\1\31\213\377(\31\213\377_"
"\31\213\377\222\31\213\377\270\31\213\377\321\31\213\377\343\31\213\377\355"
"\31\213\377\355\31\213\377\343\31\213\377\321\31\213\377\270\31\213\377\222"
"\31\213\377_\31\213\377(\1\1\377\1\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"
"\0\0\0\0\0\0\0\0\0",
#if 0
};
#endif

View file

@ -0,0 +1 @@
#include "../eduke32_icon.c"

View file

@ -0,0 +1,72 @@
#define NEED_COMMCTRL_H
#include "windows_inc.h"
#include "startwin.editor.h"
RSRC_ICON ICON "../build_icon.ico"
RSRC_BMP BITMAP "../build.bmp"
WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 260, 200
STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU
CAPTION "Startup"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE, 0, 0, 66, 172
CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 250, 170
CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 180, 48, 14
CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 207, 180, 48, 14
CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32
END
WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 279, 168
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
CAPTION "Dialog"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "&2D Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 8, 50, 8
CONTROL "", IDC2DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 6, 80, 56
CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 148, 8, 49, 10
CONTROL "&3D Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 24, 50, 8
CONTROL "", IDC3DVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 22, 80, 56
CONTROL "&Always show this window at startup", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8
END
#define FILEVER 1,9,9,9
#define PRODUCTVER 1,9,9,9
#define STRFILEVER "2.0.0devel\0"
#define STRPRODUCTVER "2.0.0devel\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION FILEVER
PRODUCTVERSION PRODUCTVER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Mapster32 for EDuke32"
VALUE "FileVersion", STRFILEVER
VALUE "InternalName", "Mapster32"
VALUE "LegalCopyright", "Copyright © 2015 EDuke32 Developers, 1996, 2003 3D Realms Entertainment"
VALUE "LegalTrademarks", "Duke Nukem® is a Registered Trademark of Gearbox Software, LLC."
VALUE "OriginalFilename", "mapster32.exe"
VALUE "ProductName", "Mapster32"
VALUE "ProductVersion", STRPRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
1 24 "../manifest.build.xml"

View file

@ -0,0 +1 @@
#include "../eduke32_icon.c"

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

View file

@ -0,0 +1,66 @@
#define NEED_COMMCTRL_H
#include "windows_inc.h"
#include "startwin.game.h"
RSRC_ICON ICON "game_icon.ico"
WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 215, 60
STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU
CAPTION "Startup"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE, 0, 0, 0, 62
CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 205, 35
CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 111, 43, 48, 14
CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 164, 43, 48, 14
CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32
END
WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 229, 58
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
CAPTION "Dialog"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "&Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 6, 50, 8
CONTROL "", IDCVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 4, 86, 56
CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 6, 46, 10
END
#define FILEVER 0,0,0,0
#define PRODUCTVER 0,0,0,0
#define STRFILEVER ""
#define STRPRODUCTVER ""
VS_VERSION_INFO VERSIONINFO
FILEVERSION FILEVER
PRODUCTVERSION PRODUCTVER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "Ion Fury"
VALUE "FileVersion", STRFILEVER
VALUE "InternalName", "Ion Fury"
VALUE "LegalCopyright", "© 2019 Voidpoint, LLC and EDuke32 developers"
VALUE "OriginalFilename", "fury.exe"
VALUE "ProductName", "Ion Fury"
VALUE "ProductVersion", STRPRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
1 24 "manifest.game.xml"

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="Ion Fury"
type="win32"
/>
<description>Ion Fury</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>

Binary file not shown.

After

Width:  |  Height:  |  Size: 328 KiB

View file

@ -0,0 +1 @@
#include "eduke32_icon.c"

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View file

@ -0,0 +1,80 @@
#define NEED_COMMCTRL_H
#include "../../build/include/windows_inc.h"
#include "../src/startwin.game.h"
RSRC_ICON ICON "game_icon.ico"
RSRC_BMP BITMAP "game.bmp"
WIN_STARTWIN DIALOGEX DISCARDABLE 20, 40, 260, 200
STYLE DS_MODALFRAME | DS_CENTER | DS_SETFONT | DS_FIXEDSYS | WS_OVERLAPPED | WS_CAPTION | WS_VISIBLE | WS_SYSMENU
CAPTION "Startup"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "", WIN_STARTWIN_BITMAP, "STATIC", SS_BITMAP | SS_CENTERIMAGE | WS_CHILD | WS_VISIBLE, 0, 0, 66, 172
CONTROL "", WIN_STARTWIN_TABCTL, WC_TABCONTROL, WS_CLIPSIBLINGS | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 5, 250, 170
CONTROL "&Start", WIN_STARTWIN_START, "BUTTON", BS_DEFPUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 180, 48, 14
CONTROL "&Cancel", WIN_STARTWIN_CANCEL, "BUTTON", BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 207, 180, 48, 14
CONTROL "", WIN_STARTWIN_MESSAGES, "EDIT", ES_MULTILINE | ES_READONLY | WS_CHILD | WS_VSCROLL, 0, 0, 32, 32
END
WIN_STARTWINPAGE_CONFIG DIALOGEX DISCARDABLE 20, 40, 279, 168
STYLE DS_SETFONT | DS_FIXEDSYS | DS_CONTROL | WS_CHILD
CAPTION "Dialog"
FONT 8, "MS Shell Dlg"
BEGIN
CONTROL "&Video mode:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 6, 50, 8
CONTROL "", IDCVMODE, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 4, 86, 56
CONTROL "&Fullscreen", IDCFULLSCREEN, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 154, 6, 46, 10
#if defined POLYMER && POLYMER != 0
CONTROL "&Polymer", IDCPOLYMER, "BUTTON", BS_CHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 203, 6, 40, 10
#endif
CONTROL "Input devices:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 20, 50, 8
CONTROL "", IDCINPUT, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 60, 19, 86, 56
CONTROL "&Game:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 35, 100, 8
CONTROL "", IDCDATA, "LISTBOX", LBS_NOINTEGRALHEIGHT | LBS_USETABSTOPS | LBS_STANDARD | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 10, 45, 226, 43
CONTROL "Custom game content &directory:", -1, "STATIC", SS_LEFT | WS_CHILD | WS_VISIBLE, 5, 90, 160, 8
CONTROL "", IDCGAMEDIR, "COMBOBOX", CBS_DROPDOWNLIST | WS_CHILD | WS_VISIBLE | WS_VSCROLL | WS_TABSTOP, 10, 99, 226, 156
CONTROL "&Enable ""autoload"" folder", IDCAUTOLOAD, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 5, 116, 100, 8
CONTROL "&Always show this window at startup", IDCALWAYSSHOW, "BUTTON", BS_AUTOCHECKBOX | WS_CHILD | WS_VISIBLE | WS_TABSTOP, 118, 116, 140, 8
END
#define FILEVER 1,9,9,9
#define PRODUCTVER 1,9,9,9
#define STRFILEVER "2.0.0devel\0"
#define STRPRODUCTVER "2.0.0devel\0"
VS_VERSION_INFO VERSIONINFO
FILEVERSION FILEVER
PRODUCTVERSION PRODUCTVER
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
FILEFLAGS 0x3L
#else
FILEFLAGS 0x2L
#endif
FILEOS 0x40004L
FILETYPE 0x1L
FILESUBTYPE 0x0L
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904b0"
BEGIN
VALUE "FileDescription", "EDuke32"
VALUE "FileVersion", STRFILEVER
VALUE "InternalName", "EDuke32"
VALUE "LegalCopyright", "Copyright © 2018 EDuke32 Developers, 1996, 2003 3D Realms Entertainment"
VALUE "LegalTrademarks", "Duke Nukem® is a Registered Trademark of Gearbox Software, LLC."
VALUE "OriginalFilename", "eduke32.exe"
VALUE "ProductName", "EDuke32"
VALUE "ProductVersion", STRPRODUCTVER
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
1 24 "manifest.game.xml"

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="EDuke32.Mapster32"
type="win32"
/>
<description>Mapster32 for EDuke32</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>

View file

@ -0,0 +1,42 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
<asmv3:application>
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
<dpiAware>true</dpiAware>
<dpiAwareness xmlns="http://schemas.microsoft.com/SMI/2016/WindowsSettings">PerMonitorV2</dpiAwareness>
</asmv3:windowsSettings>
</asmv3:application>
<assemblyIdentity
version="1.0.0.0"
processorArchitecture="*"
name="EDuke32"
type="win32"
/>
<description>EDuke32</description>
<dependency>
<dependentAssembly>
<assemblyIdentity
type="win32"
name="Microsoft.Windows.Common-Controls"
version="6.0.0.0"
processorArchitecture="*"
publicKeyToken="6595b64144ccf1df"
language="*"
/>
</dependentAssembly>
</dependency>
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
<application>
<!-- Windows Vista -->
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
<!-- Windows 7 -->
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
<!-- Windows 8 -->
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
<!-- Windows 8.1 -->
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
<!-- Windows 10 -->
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
</application>
</compatibility>
</assembly>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,49 @@
#include "aistuff.h"
extern int localclock;
int TimeSlot[KMaxTimeSlots];
void InitTimeSlot()
{
for (int i = 0; i < KMaxTimeSlots; i++) {
TimeSlot[i] = 0;
}
}
int GrabTimeSlot(int nVal)
{
return -1;
// BJD - below code found in an early Powerslave release. Doesn't seem to do anything and is missing in later releases.
#if 0
int ebx = -1;
int esi;
for (int i = 0; i < nVal; i++)
{
int nSlot = (localclock + i) & 0xF;
if (ebx >= 0)
{
if (esi <= TimeSlot[nSlot]) {
continue;
}
}
esi = TimeSlot[nSlot];
ebx = i;
}
esi = localclock;
int edx = ebx;
while (edx < 16)
{
TimeSlot[(edx + esi) & 0xF]++;
edx += nVal;
}
#endif
}

View file

@ -0,0 +1,29 @@
#ifndef __aistuff_h__
#define __aistuff_h__
#include "anubis.h"
#include "bubbles.h"
#include "mummy.h"
#include "rex.h"
#include "roach.h"
#include "scorp.h"
#include "spider.h"
#include "lion.h"
#include "set.h"
#include "queen.h"
#include "wasp.h"
#include "rat.h"
#include "gun.h"
#include "grenade.h"
#include "snake.h"
#include "fish.h"
#include "lavadude.h"
#include "bullet.h"
#define KMaxTimeSlots 16
void InitTimeSlot();
int GrabTimeSlot(int nVal);
#endif

View file

@ -0,0 +1,328 @@
#include "engine.h"
#include "anims.h"
#include "sequence.h"
#include "runlist.h"
#include "exhumed.h"
#include "sound.h"
#include "random.h"
#include "init.h"
#include <assert.h>
#define kMaxAnims 400
short nMagicSeq = -1;
short nPreMagicSeq = -1;
short nSavePointSeq = -1;
short nAnimsFree = 0;
short AnimRunRec[kMaxAnims];
short AnimsFree[kMaxAnims];
Anim AnimList[kMaxAnims];
uchar AnimFlags[kMaxAnims];
void InitAnims()
{
for (int i = 0; i < kMaxAnims; i++) {
AnimsFree[i] = i;
}
nAnimsFree = kMaxAnims;
nMagicSeq = SeqOffsets[kSeqItems] + 21;
nPreMagicSeq = SeqOffsets[kSeqMagic2];
nSavePointSeq = SeqOffsets[kSeqItems] + 12;
}
void DestroyAnim(int nAnim)
{
// if (nAnim == 386) {
if (nAnim == 365) {
int gasd = 123;
}
short nSprite = AnimList[nAnim].nSprite;
if (nSprite >= 0)
{
StopSpriteSound(nSprite);
runlist_SubRunRec(AnimRunRec[nAnim]);
runlist_DoSubRunRec(sprite[nSprite].extra);
runlist_FreeRun(sprite[nSprite].lotag - 1);
}
AnimsFree[nAnimsFree] = nAnim;
nAnimsFree++;
}
int BuildAnim(int nSprite, int val, int val2, int x, int y, int z, int nSector, int nRepeat, int nFlag)
{
if (!nAnimsFree)
return -1;
if (nSector >= kMaxSectors) {
int asdffdg = 123;
}
nAnimsFree--;
short nAnim = AnimsFree[nAnimsFree];
// if (nAnim == 386) {
if (nAnim == 365) {
int blag = 123;
}
if (nSprite == -1) {
nSprite = insertsprite(nSector, 500);
// assert(nSprite != -1);
}
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
sprite[nSprite].cstat = 0;
if (nFlag & 4)
{
sprite[nSprite].pal = 4;
sprite[nSprite].shade = -64;
}
else
{
sprite[nSprite].pal = 0;
sprite[nSprite].shade = -12;
}
sprite[nSprite].clipdist = 10;
sprite[nSprite].xrepeat = nRepeat;
sprite[nSprite].yrepeat = nRepeat;
sprite[nSprite].picnum = 1;
sprite[nSprite].ang = 0;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
// CHECKME - where is hitag set otherwise?
if (sprite[nSprite].statnum < 900) {
sprite[nSprite].hitag = -1;
}
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].owner = -1;
sprite[nSprite].extra = runlist_AddRunRec(sprite[nSprite].lotag - 1, nAnim | 0x100000);
AnimRunRec[nAnim] = runlist_AddRunRec(NewRun, nAnim | 0x100000);
AnimList[nAnim].nSprite = nSprite;
AnimFlags[nAnim] = nFlag;
AnimList[nAnim].field_2 = 0;
AnimList[nAnim].nSeq = SeqOffsets[val] + val2;
AnimList[nAnim].field_4 = 256;
if (nFlag & 0x80) {
sprite[nSprite].cstat |= 0x2; // set transluscence
}
return nAnim;
}
short GetAnimSprite(short nAnim)
{
return AnimList[nAnim].nSprite;
}
void FuncAnim(int a, int, int nRun)
{
short nAnim = RunData[nRun].nVal;
assert(nAnim >= 0 && nAnim < kMaxAnims);
short nSprite = AnimList[nAnim].nSprite;
short nSeq = AnimList[nAnim].nSeq;
assert(nSprite != -1);
int nMessage = a & 0x7F0000;
switch (nMessage)
{
case 0x20000:
{
short var_1C = AnimList[nAnim].field_2;
if (!(sprite[nSprite].cstat & 0x8000))
{
seq_MoveSequence(nSprite, nSeq, var_1C);
}
if (sprite[nSprite].statnum == kStatIgnited)
{
short nHitag = sprite[nSprite].hitag;
if (nHitag > -1)
{
sprite[nSprite].x = sprite[nHitag].x;
sprite[nSprite].y = sprite[nHitag].y;
sprite[nSprite].z = sprite[nHitag].z;
if (sprite[nHitag].sectnum != sprite[nSprite].sectnum)
{
if (sprite[nHitag].sectnum < 0 || sprite[nHitag].sectnum >= kMaxSectors)
{
DestroyAnim(nAnim);
mydeletesprite(nSprite);
return;
}
else
{
mychangespritesect(nSprite, sprite[nHitag].sectnum);
}
}
if (!var_1C)
{
if (sprite[nHitag].cstat != 0x8000)
{
short hitag2 = sprite[nHitag].hitag;
sprite[nHitag].hitag--;
if (hitag2 >= 15)
{
runlist_DamageEnemy(nHitag, -1, (sprite[nHitag].hitag - 14) * 2);
if (sprite[nHitag].shade < 100)
{
sprite[nHitag].pal = 0;
sprite[nHitag].shade++;
}
if (!(sprite[nHitag].cstat & 101))
{
DestroyAnim(nAnim);
mydeletesprite(nSprite);
return;
}
goto loc_2D755;
}
}
sprite[nHitag].hitag = 1;
DestroyAnim(nAnim);
mydeletesprite(nSprite);
}
}
}
// loc_2D755
loc_2D755:
AnimList[nAnim].field_2++;
if (AnimList[nAnim].field_2 >= SeqSize[nSeq])
{
if (AnimFlags[nAnim] & 0x10)
{
AnimList[nAnim].field_2 = 0;
}
else if (nSeq == nPreMagicSeq)
{
AnimList[nAnim].field_2 = 0;
AnimList[nAnim].nSeq = nMagicSeq;
short nAnimSprite = AnimList[nAnim].nSprite;
AnimFlags[nAnim] |= 0x10;
sprite[nAnimSprite].cstat |= 2;
}
else if (nSeq == nSavePointSeq)
{
AnimList[nAnim].field_2 = 0;
AnimList[nAnim].nSeq++;
AnimFlags[nAnim] |= 0x10;
}
else
{
DestroyAnim(nAnim);
mydeletesprite(nSprite);
}
return;
}
return;
}
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, nSeq, AnimList[nAnim].field_2, 0x101);
tsprite[a & 0xFFFF].owner = -1;
return;
}
case 0xA0000:
{
return;
}
default:
{
DebugOut("unknown msg %x for anim\n", a & 0x7F0000);
return;
}
}
}
void BuildExplosion(short nSprite)
{
short nSector = sprite[nSprite].sectnum;
int edx = 36;
if (SectFlag[nSector] & kSectUnderwater)
{
edx = 75;
}
else if (sprite[nSprite].z == sector[nSector].floorz)
{
edx = 34;
}
BuildAnim(-1, edx, 0, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, sprite[nSprite].xrepeat, 4);
}
int BuildSplash(int nSprite, int nSector)
{
int nRepeat, nSound;
if (sprite[nSprite].statnum != 200)
{
nRepeat = sprite[nSprite].xrepeat + (RandomWord() % sprite[nSprite].xrepeat);
nSound = kSound0;
}
else
{
nRepeat = 20;
nSound = kSound1;
}
int bIsLava = SectFlag[nSector] & kSectLava;
int edx, nFlag;
if (bIsLava)
{
edx = 43;
nFlag = 4;
}
else
{
edx = 35;
nFlag = 0;
}
int nAnim = BuildAnim(-1, edx, 0, sprite[nSprite].x, sprite[nSprite].y, sector[nSector].floorz, nSector, nRepeat, nFlag);
if (!bIsLava)
{
D3PlayFX(StaticSound[nSound] | 10, AnimList[nAnim].nSprite);
}
return AnimList[nAnim].nSprite;
}

View file

@ -0,0 +1,27 @@
#ifndef __anims_h__
#define __anims_h__
#include "typedefs.h"
struct Anim
{
short nSeq;
short field_2;
short field_4;
short nSprite;
};
extern Anim AnimList[];
extern uchar AnimFlags[];
void InitAnims();
void DestroyAnim(int nAnim);
int BuildAnim(int nSprite, int val, int val2, int x, int y, int z, int nSector, int nRepeat, int nFlag);
short GetAnimSprite(short nAnim);
void FuncAnim(int, int, int);
void BuildExplosion(short nSprite);
int BuildSplash(int nSprite, int nSector);
#endif

View file

@ -0,0 +1,471 @@
#include "exhumed.h"
#include "anubis.h"
#include "engine.h"
#include "runlist.h"
#include "sequence.h"
#include "move.h"
#include "bullet.h"
#include "random.h"
#include "items.h"
#include "object.h"
#include "sound.h"
#include "trigdat.h"
#include <assert.h>
#define kMaxAnubis 80
struct Anubis
{
short nHealth;
short nFrame;
short nAction;
short nSprite;
short nTarget;
short f;
short g;
short h;
};
Anubis AnubisList[kMaxAnubis];
short AnubisSprite = -1;
short AnubisCount = -1;
static actionSeq ActionSeq[] = {
{ 0, 0 },
{ 8, 0 },
{ 16, 0 },
{ 24, 0 },
{ 32, 0 },
{ -1, 0 },
{ 46, 1 },
{ 46, 1 },
{ 47, 1 },
{ 49, 1 },
{ 49, 1 },
{ 40, 1 },
{ 42, 1 },
{ 41, 1 },
{ 43, 1 },
};
short nAnubisDrum = 0;
void InitAnubis()
{
AnubisCount = kMaxAnubis;
AnubisSprite = 1;
nAnubisDrum = 1;
}
int BuildAnubis(int nSprite, int x, int y, int z, int nSector, int nAngle, BOOL bIsDrummer)
{
AnubisCount--;
short nAnubis = AnubisCount;
if (nAnubis < 0) {
return -1;
}
if (nSprite == -1)
{
nSprite = insertsprite(nSector, 101);
}
else
{
changespritestat(nSprite, 101);
x = sprite[nSprite].x;
y = sprite[nSprite].y;
z = sector[sprite[nSprite].sectnum].floorz;
nAngle = sprite[nSprite].ang;
}
assert(nSprite >=0 && nSprite < kMaxSprites);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
sprite[nSprite].cstat = 0x101;
sprite[nSprite].xoffset = 0;
sprite[nSprite].shade = -12;
sprite[nSprite].yoffset = 0;
sprite[nSprite].picnum = 1;
sprite[nSprite].pal = sector[sprite[nSprite].sectnum].ceilingpal;
sprite[nSprite].clipdist = 60;
sprite[nSprite].ang = nAngle;
sprite[nSprite].xrepeat = 40;
sprite[nSprite].yrepeat = 40;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].hitag = 0;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].extra = -1;
// GrabTimeSlot(3);
if (bIsDrummer)
{
AnubisList[nAnubis].nAction = nAnubisDrum + 6;
nAnubisDrum++;
if (nAnubisDrum >= 5) {
nAnubisDrum = 0;
}
}
else
{
AnubisList[nAnubis].nAction = 0;
}
AnubisList[nAnubis].nHealth = 540;
AnubisList[nAnubis].nFrame = 0;
AnubisList[nAnubis].nSprite = nSprite;
AnubisList[nAnubis].nTarget = -1;
AnubisList[nAnubis].g = 0;
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nAnubis | 0x90000);
runlist_AddRunRec(NewRun, nAnubis | 0x90000);
nCreaturesLeft++;
return nAnubis | 0x90000;
}
void FuncAnubis(int a, int nDamage, int nRun)
{
short nAnubis = RunData[nRun].nVal;
int var_14 = 0;
assert(nAnubis >= 0 && nAnubis < kMaxAnubis);
short nSprite = AnubisList[nAnubis].nSprite;
short nAction = AnubisList[nAnubis].nAction;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
case 0x20000:
{
if (nAction < 11) {
Gravity(nSprite);
}
short nSeq = SeqOffsets[kSeqAnubis] + ActionSeq[nAction].a;
seq_MoveSequence(nSprite, nSeq, AnubisList[nAnubis].nFrame);
sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, AnubisList[nAnubis].nFrame);
AnubisList[nAnubis].nFrame++;
if (AnubisList[nAnubis].nFrame >= SeqSize[nSeq])
{
AnubisList[nAnubis].nFrame = 0;
var_14 = 1;
}
short nTarget = AnubisList[nAnubis].nTarget;
short nFrame = SeqBase[nSeq] + AnubisList[nAnubis].nFrame;
short nFlag = FrameFlag[nFrame];
int c;
if (nAction > 0 && nAction < 11) {
c = MoveCreatureWithCaution(nSprite);
}
switch (nAction)
{
case 0:
{
if ((nAnubis & 0x1F) == (totalmoves & 0x1F))
{
if (nTarget < 0) {
nTarget = FindPlayer(nSprite, 100);
}
if (nTarget >= 0)
{
D3PlayFX(StaticSound[kSound8], nSprite);
AnubisList[nAnubis].nAction = 1;
AnubisList[nAnubis].nFrame = 0;
AnubisList[nAnubis].nTarget = nTarget;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 2;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 2;
}
}
return;
}
case 1:
{
if ((nAnubis & 0x1F) == (totalmoves & 0x1F))
{
PlotCourseToSprite(nSprite, nTarget);
sprite[nSprite].xvel = Sin((sprite[nSprite].ang & 0xFFF8) + 512) >> 2;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang & 0xFFF8) >> 2;
}
switch (c & 0xC000)
{
case 0xC000:
{
if ((c & 0x3FFF) == nTarget)
{
int nAng = getangle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y);
int nAngDiff = AngleDiff(sprite[nSprite].ang, nAng);
if (nAngDiff < 64)
{
AnubisList[nAnubis].nAction = 2;
AnubisList[nAnubis].nFrame = 0;
}
break; // only break if condition met
}
// else we fall through to 0x8000
}
case 0x8000:
{
sprite[nSprite].ang += 256;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 2;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 2;
break;
}
default:
{
if (AnubisList[nAnubis].g)
{
AnubisList[nAnubis].g--;
}
else
{
AnubisList[nAnubis].g = 60;
if (cansee(sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z - GetSpriteHeight(nSprite), sprite[nSprite].sectnum,
sprite[nTarget].x, sprite[nTarget].y, sprite[nTarget].z - GetSpriteHeight(nTarget), sprite[nTarget].sectnum))
{
AnubisList[nAnubis].nAction = 3;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].ang = GetMyAngle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y);
AnubisList[nAnubis].nFrame = 0;
}
}
break;
}
}
break;
}
case 2:
{
if (nTarget == -1)
{
AnubisList[nAnubis].nAction = 0;
AnubisList[nAnubis].g = 50;
}
else
{
if (PlotCourseToSprite(nSprite, nTarget) >= 768)
{
AnubisList[nAnubis].nAction = 1;
}
else
{
if (nFlag & 0x80)
{
runlist_DamageEnemy(nTarget, nSprite, 7);
}
}
}
break;
}
case 3:
{
if (var_14)
{
AnubisList[nAnubis].nAction = 1;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 2;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 2;
AnubisList[nAnubis].nFrame = 0;
}
else
{
// loc_25718:
if (nFlag & 0x80)
{
BuildBullet(nSprite, 8, 0, 0, -1, sprite[nSprite].ang, nTarget + 10000, 1);
}
}
return;
}
case 4:
case 5:
{
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
if (var_14)
{
AnubisList[nAnubis].nAction = 1;
AnubisList[nAnubis].nFrame = 0;
}
return;
}
case 6:
case 7:
case 8:
case 9:
case 10:
{
if (var_14)
{
AnubisList[nAnubis].nAction = (RandomSize(3) % 5) + 6;
AnubisList[nAnubis].nFrame = 0;
}
return;
}
case 11:
case 12:
{
if (var_14)
{
AnubisList[nAnubis].nAction = nAction + 2;
AnubisList[nAnubis].nFrame = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
}
return;
}
case 13:
case 14:
{
sprite[nSprite].cstat &= 0xFEFE;
return;
}
default:
return;
}
// loc_2564C:
if (nAction && nTarget != -1)
{
if (!(sprite[nTarget].cstat & 0x101))
{
AnubisList[nAnubis].nAction = 0;
AnubisList[nAnubis].nFrame = 0;
AnubisList[nAnubis].g = 100;
AnubisList[nAnubis].nTarget = -1;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
}
}
return;
}
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, SeqOffsets[kSeqAnubis] + ActionSeq[nAction].a, AnubisList[nAnubis].nFrame, ActionSeq[nAction].b);
break;
}
case 0xA0000: // fall through to next case
{
if (nAction >= 11) {
return;
}
nDamage = runlist_CheckRadialDamage(nSprite);
}
case 0x80000:
{
if (nDamage)
{
if (AnubisList[nAnubis].nHealth <= 0)
return;
AnubisList[nAnubis].nHealth -= nDamage;
if (AnubisList[nAnubis].nHealth > 0)
{
short nTarget = a & 0xFFFF;
// loc_258D6:
if (nTarget < 0) {
return;
}
if (sprite[nTarget].statnum == 100 || sprite[nTarget].statnum < 199)
{
if (!RandomSize(5)) {
AnubisList[nAnubis].nTarget = nTarget;
}
}
if (RandomSize(1))
{
if (nAction >= 6 && nAction <= 10)
{
int nThisSprite = insertsprite(sprite[nSprite].sectnum, 98);
sprite[nThisSprite].x = sprite[nSprite].x;
sprite[nThisSprite].y = sprite[nSprite].y;
sprite[nThisSprite].z = sector[sprite[nThisSprite].sectnum].floorz;
sprite[nThisSprite].yrepeat = 40;
sprite[nThisSprite].xrepeat = 40;
sprite[nThisSprite].shade = -64;
BuildObject(nThisSprite, 2, 0);
}
AnubisList[nAnubis].nAction = 4;
AnubisList[nAnubis].nFrame = 0;
}
else
{
// loc_259B5:
D3PlayFX(StaticSound[kSound39], nSprite);
}
}
else
{
// he ded.
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].z = sector[sprite[nSprite].sectnum].floorz;
sprite[nSprite].cstat &= 0xFEFE;
AnubisList[nAnubis].nHealth = 0;
nCreaturesLeft--;
if (nAction < 11)
{
DropMagic(nSprite);
AnubisList[nAnubis].nAction = (nMessage == 0xA0000) + 11;
AnubisList[nAnubis].nFrame = 0;
}
}
}
return;
}
default:
{
DebugOut("unknown msg %d for Anubis\n", a & 0x7F0000);
return;
}
}
}

View file

@ -0,0 +1,12 @@
#ifndef __anubis_h__
#define __anubis_h__
#include "typedefs.h"
void InitAnubis();
int BuildAnubis(int nSprite, int x, int y, int z, int nSector, int nAngle, BOOL bIsDrummer);
void FuncAnubis(int a, int b, int c);
#endif

View file

@ -0,0 +1,223 @@
#include "bubbles.h"
#include "runlist.h"
#include "exhumed.h"
#include "random.h"
#include "engine.h"
#include "sequence.h"
#include "move.h"
#include "init.h"
#include "runlist.h"
#include "init.h"
#include "anims.h"
#include <assert.h>
#define kMaxBubbles 200
#define kMaxMachines 125
struct Bubble
{
short _0;
short _2;
short nSprite;
short _6;
};
struct machine
{
short _0;
short nSprite;
short _4;
};
short BubbleCount = 0;
short nFreeCount;
short nMachineCount;
uchar nBubblesFree[kMaxBubbles];
machine Machine[kMaxMachines];
Bubble BubbleList[kMaxBubbles];
void InitBubbles()
{
BubbleCount = 0;
nMachineCount = 0;
for (int i = 0; i < kMaxBubbles; i++) {
nBubblesFree[i] = i;
}
nFreeCount = 0;
}
void DestroyBubble(short nBubble)
{
short nSprite = BubbleList[nBubble].nSprite;
runlist_DoSubRunRec(sprite[nSprite].lotag - 1);
runlist_DoSubRunRec(sprite[nSprite].owner);
runlist_SubRunRec(BubbleList[nBubble]._6);
mydeletesprite(nSprite);
nBubblesFree[nFreeCount] = nBubble;
nFreeCount++;
}
short GetBubbleSprite(short nBubble)
{
return BubbleList[nBubble].nSprite;
}
int BuildBubble(int x, int y, int z, short nSector)
{
int nSize = RandomSize(3);
if (nSize > 4) {
nSize -= 4;
}
if (nFreeCount <= 0) {
return -1;
}
nFreeCount--;
uchar nBubble = nBubblesFree[nFreeCount];
int nSprite = insertsprite(nSector, 402);
assert(nSprite >= 0 && nSprite < kMaxSprites);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
sprite[nSprite].cstat = 0;
sprite[nSprite].shade = -32;
sprite[nSprite].pal = 0;
sprite[nSprite].clipdist = 5;
sprite[nSprite].xrepeat = 40;
sprite[nSprite].yrepeat = 40;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].picnum = 1;
sprite[nSprite].ang = inita;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = -1200;
sprite[nSprite].hitag = -1;
sprite[nSprite].extra = -1;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
// GrabTimeSlot(3);
BubbleList[nBubble].nSprite = nSprite;
BubbleList[nBubble]._0 = 0;
BubbleList[nBubble]._2 = SeqOffsets[kSeqBubble] + nSize;
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nBubble | 0x140000);
BubbleList[nBubble]._6 = runlist_AddRunRec(NewRun, nBubble | 0x140000);
return nBubble | 0x140000;
}
void FuncBubble(int a, int b, int nRun)
{
short nBubble = RunData[nRun].nVal;
assert(nBubble >= 0 && nBubble < kMaxBubbles);
short nSprite = BubbleList[nBubble].nSprite;
short dx = BubbleList[nBubble]._2;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
case 0x20000:
{
seq_MoveSequence(nSprite, dx, BubbleList[nBubble]._0);
BubbleList[nBubble]._0++;
if (BubbleList[nBubble]._0 >= SeqSize[dx]) {
BubbleList[nBubble]._0 = 0;
}
sprite[nSprite].z += sprite[nSprite].zvel;
short nSector = sprite[nSprite].sectnum;
if (sprite[nSprite].z <= sector[nSector].ceilingz)
{
short nSectAbove = SectAbove[nSector];
if (sprite[nSprite].hitag > -1 && nSectAbove != -1) {
BuildAnim(-1, 70, 0, sprite[nSprite].x, sprite[nSprite].y, sector[nSectAbove].floorz, nSectAbove, 64, 0);
}
DestroyBubble(nBubble);
}
return;
}
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, dx, BubbleList[nBubble]._0, 1);
tsprite[a & 0xFFFF].owner = -1;
return;
}
case 0x80000:
case 0xA0000:
return;
default:
DebugOut("unknown msg %d for Bubble\n", nMessage);
return;
}
}
void DoBubbleMachines()
{
for (int i = 0; i < nMachineCount; i++)
{
Machine[i]._0--;
if (Machine[i]._0 <= 0)
{
Machine[i]._0 = (RandomWord() % Machine[i]._4) + 30;
int nSprite = Machine[i].nSprite;
BuildBubble(sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum);
}
}
}
void BuildBubbleMachine(int nSprite)
{
if (nMachineCount >= kMaxMachines) {
bail2dos("too many bubble machines in level %d\n", levelnew);
}
Machine[nMachineCount]._4 = 75;
Machine[nMachineCount].nSprite = nSprite;
Machine[nMachineCount]._0 = Machine[nMachineCount]._4;
nMachineCount++;
sprite[nSprite].cstat = 0x8000u;
}
void DoBubbles(int nPlayer)
{
int x, y, z;
short nSector;
WheresMyMouth(nPlayer, &x, &y, &z, &nSector);
int nBubble = BuildBubble(x, y, z, nSector);
int nSprite = GetBubbleSprite(nBubble);
sprite[nSprite].hitag = nPlayer;
}

View file

@ -0,0 +1,13 @@
#ifndef __bubbles_h__
#define __bubbles_h__
void InitBubbles();
void BuildBubbleMachine(int nSprite);
void DoBubbleMachines();
void DoBubbles(int nPlayer);
void FuncBubble(int, int, int);
#endif

View file

@ -0,0 +1,894 @@
#include "engine.h"
#include "bullet.h"
#include "runlist.h"
#include "anims.h"
#include "sequence.h"
#include "exhumed.h"
#include "sound.h"
#include "init.h"
#include "move.h"
#include "player.h"
#include "trigdat.h"
#include "random.h"
#include "gun.h"
#include "names.h"
#include "lighting.h"
#include <string.h>
#include <assert.h>
#ifndef __WATCOMC__
//#include <cmath>
#else
//#include <math.h>
#include <stdlib.h>
#endif
#define kMaxBullets 500
short BulletFree[kMaxBullets];
// 32 bytes
struct Bullet
{
short nSeq; // 0
short field_2; // 2
short nSprite; // 4
short field_6;
short field_8;
short nType;
short field_C;
short field_E;
short field_10;
uchar field_12;
uchar field_13;
int x;
int y;
int z;
};
Bullet BulletList[kMaxBullets];
short nBulletEnemy[kMaxBullets];
int nBulletsFree;
int lasthitz, lasthitx, lasthity;
short lasthitsect, lasthitsprite, lasthitwall;
int nBulletCount = 0;
short nRadialBullet = 0;
bulletInfo BulletInfo[] = {
{ 25, 1, 20, -1, -1, 13, 0, 0, -1, 0 },
{ 25, -1, 65000, -1, 31, 73, 0, 0, -1, 0 },
{ 15, -1, 60000, -1, 31, 73, 0, 0, -1, 0 },
{ 5, 15, 2000, -1, 14, 38, 4, 5, 3, 0 },
{ 250, 100, 2000, -1, 33, 34, 4, 20, -1, 0 },
{ 200, -1, 2000, -1, 20, 23, 4, 10, -1, 0 },
{ 200, -1, 60000, 68, 68, -1, -1, 0, -1, 0 },
{ 300, 1, 0, -1, -1, -1, 0, 50, -1, 0 },
{ 18, -1, 2000, -1, 18, 29, 4, 0, -1, 0 },
{ 20, -1, 2000, 37, 11, 30, 4, 0, -1, 0 },
{ 25, -1, 3000, -1, 44, 36, 4, 15, 90, 0 },
{ 30, -1, 1000, -1, 52, 53, 4, 20, 48, 0 },
{ 20, -1, 3500, -1, 54, 55, 4, 30, -1, 0 },
{ 10, -1, 5000, -1, 57, 76, 4, 0, -1, 0 },
{ 40, -1, 1500, -1, 63, 38, 4, 10, 40, 0 },
{ 20, -1, 2000, -1, 60, 12, 0, 0, -1, 0 },
{ 5, -1, 60000, -1, 31, 76, 0, 0, -1, 0 }
};
void InitBullets()
{
nBulletCount = 0;
for (int i = 0; i < kMaxBullets; i++) {
BulletFree[i] = i;
}
nBulletsFree = kMaxBullets;
memset(nBulletEnemy, -1, sizeof(nBulletEnemy));
}
short GrabBullet()
{
nBulletsFree--;
return BulletFree[nBulletsFree];
}
void DestroyBullet(short nBullet)
{
short nSprite = BulletList[nBullet].nSprite;
runlist_DoSubRunRec(BulletList[nBullet].field_6);
runlist_DoSubRunRec(sprite[nSprite].lotag - 1);
runlist_SubRunRec(BulletList[nBullet].field_8);
StopSpriteSound(nSprite);
mydeletesprite(nSprite);
BulletFree[nBulletsFree] = nBullet;
nBulletsFree++;
}
void IgniteSprite(int nSprite)
{
sprite[nSprite].hitag += 2;
int nAnim = BuildAnim(-1, 38, 0, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, 40, 20);//276);
short nAnimSprite = GetAnimSprite(nAnim);
sprite[nAnimSprite].hitag = nSprite;
changespritestat(nAnimSprite, kStatIgnited);
short yRepeat = (tilesiz[sprite[nAnimSprite].picnum].y * 32) / nFlameHeight;
if (yRepeat < 1)
yRepeat = 1;
sprite[nAnimSprite].yrepeat = (uchar)yRepeat;
}
void BulletHitsSprite(Bullet *pBullet, short nBulletSprite, short nHitSprite, int x, int y, int z, int nSector)
{
assert(nSector >= 0 && nSector < kMaxSectors);
bulletInfo *pBulletInfo = &BulletInfo[pBullet->nType];
short nStat = sprite[nHitSprite].statnum;
switch (pBullet->nType)
{
case 0:
case 4:
case 5:
case 6:
case 7:
case 10:
case 11:
{
break;
}
case 14:
{
if (nStat > 107 || nStat == 98) {
return;
}
// else - fall through to below cases
}
case 1:
case 2:
case 8:
case 9:
case 12:
case 13:
case 15:
case 16:
{
// loc_29E59
if (!nStat || nStat > 98) {
break;
}
short nSprite = pBullet->nSprite;
if (nStat == 98)
{
short nAngle = sprite[nSprite].ang + 256;
int nRand = RandomSize(9);
sprite[nHitSprite].xvel = Sin((nAngle - nRand) + 512) * 2;
sprite[nHitSprite].yvel = Sin((nAngle - nRand)) * 2;
sprite[nHitSprite].zvel = (-(RandomSize(3) + 1)) << 8;
}
else
{
int xVel = sprite[nHitSprite].xvel;
int yVel = sprite[nHitSprite].yvel;
sprite[nHitSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 2;
sprite[nHitSprite].yvel = Sin(sprite[nSprite].ang) >> 2;
MoveCreature(nHitSprite);
sprite[nHitSprite].xvel = xVel;
sprite[nHitSprite].yvel = yVel;
}
break;
}
case 3:
{
if (nStat > 107 || nStat == 98) {
return;
}
sprite[nHitSprite].hitag++;
if (sprite[nHitSprite].hitag == 15) {
IgniteSprite(nHitSprite);
}
if (!RandomSize(2)) {
BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags);
}
return;
}
default:
break;
}
// BHS_switchBreak:
short nDamage = pBulletInfo->nDamage;
if (pBullet->field_13 > 1) {
nDamage *= 2;
}
runlist_DamageEnemy(nHitSprite, nBulletSprite, nDamage);
if (nStat <= 90 || nStat >= 199)
{
BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags);
return;
}
if (nStat < 98)
{
if (nStat <= 0)
{
BuildAnim(-1, 12, 0, x, y, z, nSector, 40, 0);
}
else if (nStat == 97)
{
return;
}
else
{
// BHS_B
BuildAnim(-1, 39, 0, x, y, z, nSector, 40, 0);
if (pBullet->nType > 2)
{
BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags);
}
}
return;
}
else
{
if (nStat == 98 || nStat == 141 || nStat == 152 || nStat == 102)
{
BuildAnim(-1, 12, 0, x, y, z, nSector, 40, 0);
}
else
{
// BHS_B
BuildAnim(-1, 39, 0, x, y, z, nSector, 40, 0);
if (pBullet->nType > 2)
{
BuildAnim(-1, pBulletInfo->field_C, 0, x, y, z, nSector, 40, pBulletInfo->nFlags);
}
}
return;
}
}
void BackUpBullet(int *x, int *y, short nAngle)
{
*x -= Sin(nAngle + 512) >> 11;
*y -= Sin(nAngle) >> 11;
}
int MoveBullet(short nBullet)
{
short hitsect = -1;
short hitwall = -1;
short hitsprite = -1;
short nType = BulletList[nBullet].nType;
short nSprite = BulletList[nBullet].nSprite;
int x = sprite[nSprite].x;
int y = sprite[nSprite].y;
int z = sprite[nSprite].z; // ebx
short nSectFlag = SectFlag[sprite[nSprite].sectnum];
int x2, y2, z2;
short var_3C = BulletList[nBullet].field_10;
int nVal;
if (var_3C < 30000)
{
short nEnemySprite = nBulletEnemy[nBullet];
if (nBulletEnemy[nBullet] <= -1) {
goto MoveBullet_goto_A; // FIXME
}
if (!(sprite[nEnemySprite].cstat & 0x101))
{
nBulletEnemy[nBullet] = -1;
MoveBullet_goto_A:
if (nType == 3)
{
if (BulletList[nBullet].field_E >= 8)
{
sprite[nSprite].xrepeat += 4;
sprite[nSprite].yrepeat += 4;
}
else
{
sprite[nSprite].xrepeat -= 1;
sprite[nSprite].yrepeat += 8;
BulletList[nBullet].z -= 200;
if (sprite[nSprite].shade < 90) {
sprite[nSprite].shade += 35;
}
if (BulletList[nBullet].field_E == 3)
{
BulletList[nBullet].nSeq = 45;
BulletList[nBullet].field_2 = 0;
sprite[nSprite].xrepeat = 40;
sprite[nSprite].yrepeat = 40;
sprite[nSprite].shade = 0;
sprite[nSprite].z += 512;
}
}
}
// loc_2A1DD
nVal = movesprite(nSprite, BulletList[nBullet].x, BulletList[nBullet].y, BulletList[nBullet].z, sprite[nSprite].clipdist >> 1, sprite[nSprite].clipdist >> 1, CLIPMASK1);
}
else
{
nVal = AngleChase(nSprite, nEnemySprite, var_3C, 0, 16);
}
if (nVal)
{
x2 = sprite[nSprite].x;
y2 = sprite[nSprite].y;
z2 = sprite[nSprite].z;
hitsect = sprite[nSprite].sectnum;
if (nVal & 0x30000)
{
hitwall = nVal & 0x3FFF;
goto loc_2A48A;
}
else
{
if ((nVal & 0xC000) == 0x8000)
{
hitwall = nVal & 0x3FFF;
goto loc_2A48A;
}
else if ((nVal & 0xC000) == 0xC000)
{
hitsprite = nVal & 0x3FFF;
goto loc_2A405;
}
else {
goto loc_2A25F;
}
}
}
else
{
loc_2A25F:
// sprite[nSprite].sectnum may have changed since we set nSectFlag ?
short nFlagVal = nSectFlag ^ SectFlag[sprite[nSprite].sectnum];
if (nFlagVal & kSectUnderwater)
{
DestroyBullet(nBullet);
nVal = 1;
}
if (nVal) {
return nVal;
}
if (nType == 15)
{
return nVal;
}
if (nType != 3)
{
AddFlash(sprite[nSprite].sectnum, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, nVal);
if (sprite[nSprite].pal != 5) {
sprite[nSprite].pal = 1;
}
}
}
}
else
{
nVal = 1;
if (nBulletEnemy[nBullet] > -1)
{
hitsprite = nBulletEnemy[nBullet];
x2 = sprite[hitsprite].x;
y2 = sprite[hitsprite].y;
z2 = sprite[hitsprite].z - (GetSpriteHeight(hitsprite) >> 1);
hitsect = sprite[hitsprite].sectnum;
}
else
{
vec3_t startPos = { x, y, z };
hitdata_t hitData = { { x2, y2, z2 }, hitsprite, hitsect, hitwall };
hitscan(&startPos, sprite[nSprite].sectnum, Sin(sprite[nSprite].ang + 512), Sin(sprite[nSprite].ang), (-Sin(BulletList[nBullet].field_C)) << 3, &hitData, CLIPMASK1);
x2 = hitData.pos.x;
y2 = hitData.pos.y;
z2 = hitData.pos.z;
hitsprite = hitData.sprite;
hitsect = hitData.sect;
hitwall = hitData.wall;
}
lasthitx = x2;
lasthity = y2;
lasthitz = z2;
lasthitsect = hitsect;
lasthitwall = hitwall;
lasthitsprite = hitsprite;
if (lasthitsprite > -1)
{
loc_2A405:
if (sprite[nSprite].pal != 5 || sprite[hitsprite].statnum != 100)
{
// assert(hitsect <= kMaxSectors);
BulletHitsSprite(&BulletList[nBullet], sprite[nSprite].owner, hitsprite, x2, y2, z2, hitsect);
}
else
{
short nPlayer = GetPlayerFromSprite(hitsprite);
if (!PlayerList[nPlayer].bIsMummified)
{
PlayerList[nPlayer].bIsMummified = kTrue;
SetNewWeapon(nPlayer, kWeaponMummified);
}
}
}
else if (hitwall > -1)
{
loc_2A48A:
if (wall[hitwall].picnum == kEnergy1)
{
short nSector = wall[hitwall].nextsector;
if (nSector > -1)
{
short nDamage = BulletInfo[BulletList[nBullet].nType].nDamage;
if (BulletList[nBullet].field_13 > 1) {
nDamage *= 2;
}
short nNormal = GetWallNormal(hitwall) & 0x7FF;
runlist_DamageEnemy(sector[nSector].extra, nNormal, nDamage);
}
}
}
// loc_2A4F5:?
if (hitsprite < 0 && hitwall < 0)
{
if ((SectBelow[hitsect] >= 0 && (SectFlag[SectBelow[hitsect]] & kSectUnderwater)) || SectDepth[hitsect])
{
sprite[nSprite].x = x2;
sprite[nSprite].y = y2;
sprite[nSprite].z = z2;
BuildSplash(nSprite, hitsect);
}
else
{
BuildAnim(-1, BulletInfo[nType].field_C, 0, x2, y2, z2, hitsect, 40, BulletInfo[nType].nFlags);
}
}
else
{
// short nType = BulletList[nBullet].nType;
if (hitwall < 0)
{
sprite[nSprite].x = x2;
sprite[nSprite].y = y2;
sprite[nSprite].z = z2;
mychangespritesect(nSprite, hitsect);
}
else
{
BackUpBullet(&x2, &y2, sprite[nSprite].ang);
if (nType != 3 || !RandomSize(2))
{
int zOffset = RandomSize(8) << 3;
if (!RandomBit()) {
zOffset = -zOffset;
}
// draws bullet puff on walls when they're shot
BuildAnim(-1, BulletInfo[nType].field_C, 0, x2, y2, z2 + zOffset, hitsect, 40, BulletInfo[nType].nFlags);
}
}
// loc_2A639:
if (BulletInfo[nType].field_10)
{
nRadialBullet = nType;
runlist_RadialDamageEnemy(nSprite, BulletInfo[nType].nDamage, BulletInfo[nType].field_10);
nRadialBullet = -1;
AddFlash(sprite[nSprite].sectnum, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, 128);
}
}
DestroyBullet(nBullet);
}
return nVal;
}
void SetBulletEnemy(short nBullet, short nEnemy)
{
if (nBullet >= 0) {
nBulletEnemy[nBullet] = nEnemy;
}
}
int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle, int val2, int val3)
{
Bullet sBullet;
if (BulletInfo[nType].field_4 > 30000)
{
if (val2 >= 10000)
{
val2 -= 10000;
short nTargetSprite = val2;
// assert(sprite[nTargetSprite].sectnum <= kMaxSectors);
if (sprite[nTargetSprite].cstat & 0x101)
{
sBullet.nType = nType;
sBullet.field_13 = val3;
sBullet.nSprite = insertsprite(sprite[nSprite].sectnum, 200);
sprite[sBullet.nSprite].ang = nAngle;
int nHeight = GetSpriteHeight(nTargetSprite);
assert(sprite[nTargetSprite].sectnum >= 0 && sprite[nTargetSprite].sectnum < kMaxSectors);
BulletHitsSprite(&sBullet, nSprite, nTargetSprite, sprite[nTargetSprite].x, sprite[nTargetSprite].y, sprite[nTargetSprite].z - (nHeight >> 1), sprite[nTargetSprite].sectnum);
mydeletesprite(sBullet.nSprite);
return -1;
}
else
{
val2 = 0;
}
}
}
if (!nBulletsFree) {
return -1;
}
short nSector;
if (sprite[nSprite].statnum != 100)
{
nSector = sprite[nSprite].sectnum;
}
else
{
nSector = nPlayerViewSect[GetPlayerFromSprite(nSprite)];
}
int nBulletSprite = insertsprite(nSector, 200);
int nHeight = GetSpriteHeight(nSprite);
nHeight = nHeight - (nHeight >> 2);
if (val1 == -1) {
val1 = -nHeight;
}
sprite[nBulletSprite].x = sprite[nSprite].x;
sprite[nBulletSprite].y = sprite[nSprite].y;
sprite[nBulletSprite].z = sprite[nSprite].z;
// why is this done here???
assert(nBulletSprite >= 0 && nBulletSprite < kMaxSprites);
short nBullet = GrabBullet();
nBulletEnemy[nBullet] = -1;
sprite[nBulletSprite].cstat = 0;
sprite[nBulletSprite].shade = -64;
if (BulletInfo[nType].nFlags & 4) {
sprite[nBulletSprite].pal = 4;
}
else {
sprite[nBulletSprite].pal = 0;
}
sprite[nBulletSprite].clipdist = 25;
short nRepeat = BulletInfo[nType].xyRepeat;
if (nRepeat < 0) {
nRepeat = 30;
}
sprite[nBulletSprite].xrepeat = nRepeat;
sprite[nBulletSprite].yrepeat = nRepeat;
sprite[nBulletSprite].xoffset = 0;
sprite[nBulletSprite].yoffset = 0;
sprite[nBulletSprite].ang = nAngle;
sprite[nBulletSprite].xvel = 0;
sprite[nBulletSprite].yvel = 0;
sprite[nBulletSprite].zvel = 0;
sprite[nBulletSprite].owner = nSprite;
sprite[nBulletSprite].lotag = runlist_HeadRun() + 1;
sprite[nBulletSprite].extra = -1;
sprite[nBulletSprite].hitag = 0;
// GrabTimeSlot(3);
BulletList[nBullet].field_10 = 0;
BulletList[nBullet].field_E = BulletInfo[nType].field_2;
BulletList[nBullet].field_2 = 0;
short nSeq;
if (BulletInfo[nType].field_8 == -1)
{
BulletList[nBullet].field_12 = 1;
nSeq = BulletInfo[nType].nSeq;
}
else
{
BulletList[nBullet].field_12 = 0;
nSeq = BulletInfo[nType].field_8;
}
BulletList[nBullet].nSeq = nSeq;
sprite[nBulletSprite].picnum = seq_GetSeqPicnum(nSeq, 0, 0);
if (nSeq == kSeqBullet) {
sprite[nBulletSprite].cstat |= 0x8000;
}
BulletList[nBullet].field_C = val2 & 0x7FF; // TODO - anglemask?
BulletList[nBullet].nType = nType;
BulletList[nBullet].nSprite = nBulletSprite;
BulletList[nBullet].field_6 = runlist_AddRunRec(sprite[nBulletSprite].lotag - 1, nBullet | 0xB0000);
BulletList[nBullet].field_8 = runlist_AddRunRec(NewRun, nBullet | 0xB0000);
BulletList[nBullet].field_13 = val3;
sprite[nBulletSprite].z += val1;
int var_18;
nSector = sprite[nBulletSprite].sectnum;
while (1)
{
if (sprite[nBulletSprite].z >= sector[nSector].ceilingz) {
break;
}
if (SectAbove[nSector] == -1)
{
sprite[nBulletSprite].z = sector[nSector].ceilingz;
break;
}
nSector = SectAbove[nSector];
mychangespritesect(nBulletSprite, nSector);
}
if (val2 < 10000)
{
var_18 = ((-Sin(val2)) * BulletInfo[nType].field_4) >> 11;
}
else
{
val2 -= 10000;
short nTargetSprite = val2;
if (BulletInfo[nType].field_4 > 30000)
{
nBulletEnemy[nBullet] = nTargetSprite;
}
else
{
nHeight = GetSpriteHeight(nTargetSprite);
int nHeightAdjust;
if (sprite[nTargetSprite].statnum == 100)
{
nHeightAdjust = nHeight >> 2;
}
else
{
nHeightAdjust = nHeight >> 1;
}
nHeight -= nHeightAdjust;
int var_20 = sprite[nTargetSprite].z - nHeight;
int x, y;
if (nSprite == -1 || sprite[nSprite].statnum == 100)
{
// loc_2ABA3:
x = sprite[nTargetSprite].x - sprite[nBulletSprite].x;
y = sprite[nTargetSprite].y - sprite[nBulletSprite].y;
}
else
{
x = sprite[nTargetSprite].x;
y = sprite[nTargetSprite].y;
if (sprite[nTargetSprite].statnum == 100)
{
int nPlayer = GetPlayerFromSprite(nTargetSprite);
if (nPlayer > -1)
{
x += ((nPlayerDX[nPlayer] << 4) - nPlayerDX[nPlayer]);
y += ((nPlayerDY[nPlayer] << 4) - nPlayerDY[nPlayer]);
}
}
else
{
short nXVel = sprite[nTargetSprite].xvel;
short nYVel = sprite[nTargetSprite].yvel;
x += (((nXVel << 2) + nXVel) << 2) >> 6;
y += (((nYVel << 2) + nYVel) << 2) >> 6;
}
y -= sprite[nBulletSprite].y;
x -= sprite[nBulletSprite].x;
nAngle = GetMyAngle(x, y);
sprite[nSprite].ang = nAngle;
}
int nSqrt = lsqrt(y*y + x*x);
if (nSqrt <= 0)
{
var_18 = 0;
}
else
{
var_18 = ((var_20 - sprite[nBulletSprite].z) * BulletInfo[nType].field_4) / nSqrt;
}
}
}
BulletList[nBullet].z = 0;
BulletList[nBullet].x = (sprite[nSprite].clipdist << 2) * Sin(nAngle + 512);
BulletList[nBullet].y = (sprite[nSprite].clipdist << 2) * Sin(nAngle);
nBulletEnemy[nBullet] = -1;
if (MoveBullet(nBullet))
{
nBulletSprite = -1;
}
else
{
BulletList[nBullet].field_10 = BulletInfo[nType].field_4;
BulletList[nBullet].x = (Sin(nAngle + 512) >> 3) * BulletInfo[nType].field_4;
BulletList[nBullet].y = (Sin(nAngle) >> 3) * BulletInfo[nType].field_4;
BulletList[nBullet].z = var_18 >> 3;
}
return (nBulletSprite & 0xFFFF) | (nBullet << 16);
}
void FuncBullet(int a, int b, int nRun)
{
short nBullet = RunData[nRun].nVal;
assert(nBullet >= 0 && nBullet < kMaxBullets);
short nSeq = SeqOffsets[BulletList[nBullet].nSeq];
short nSprite = BulletList[nBullet].nSprite;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
default:
{
DebugOut("unknown msg %x for bullet\n", a & 0x7F0000);
return;
}
case 0xA0000:
return;
case 0x90000:
{
short nSprite2 = a & 0xFFFF;
tsprite[nSprite2].statnum = 1000;
if (BulletList[nBullet].nType == 15)
{
seq_PlotArrowSequence(nSprite2, nSeq, BulletList[nBullet].field_2);
}
else
{
seq_PlotSequence(nSprite2, nSeq, BulletList[nBullet].field_2, 0);
tsprite[nSprite2].owner = -1;
}
return;
}
case 0x20000:
{
short nFlag = FrameFlag[SeqBase[nSeq] + BulletList[nBullet].field_2];
seq_MoveSequence(nSprite, nSeq, BulletList[nBullet].field_2);
if (nFlag & 0x80)
{
BuildAnim(-1, 45, 0, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, sprite[nSprite].xrepeat, 0);
}
BulletList[nBullet].field_2++;
if (BulletList[nBullet].field_2 >= SeqSize[nSeq])
{
if (!BulletList[nBullet].field_12)
{
BulletList[nBullet].nSeq = BulletInfo[BulletList[nBullet].nType].nSeq;
BulletList[nBullet].field_12++;
}
BulletList[nBullet].field_2 = 0;
}
if (BulletList[nBullet].field_E == -1)
{
MoveBullet(nBullet);
}
else
{
BulletList[nBullet].field_E--;
if (!BulletList[nBullet].field_E) {
DestroyBullet(nBullet);
}
else {
MoveBullet(nBullet);
}
}
return;
}
}
}

View file

@ -0,0 +1,38 @@
#ifndef __bullet_h__
#define __bullet_h__
// 32 bytes
struct bulletInfo
{
short nDamage; // 0
short field_2; // 2
int field_4; // 4
short field_8; // 8
short nSeq; // 10
short field_C; // 12
short nFlags;
short field_10; // damage radius?
short xyRepeat;
char pad[12];
};
extern bulletInfo BulletInfo[];
extern short nRadialBullet;
extern short lasthitsect;
extern int lasthitz;
extern int lasthitx;
extern int lasthity;
void InitBullets();
short GrabBullet();
void DestroyBullet(short nRun);
int MoveBullet(short nBullet);
void SetBulletEnemy(short nBullet, short nEnemy);
int BuildBullet(short nSprite, int nType, int ebx, int ecx, int val1, int nAngle, int val2, int val3);
void IgniteSprite(int nSprite);
void FuncBullet(int, int, int);
void BackUpBullet(int *x, int *y, short nAngle);
#endif

55
source/exhumed/src/cd.cpp Normal file
View file

@ -0,0 +1,55 @@
#include "cd.h"
#include <stdio.h>
#include <stdlib.h>
extern short word_9AC30;
int cd_check_device_present()
{
return 1;
}
int initcdaudio()
{
if (!cd_check_device_present())
{
word_9AC30 = 1;
// return to text video mode
printf("No MSCDEX driver installed!\n");
exit(0);
}
return 1;
}
void setCDaudiovolume(int val)
{
}
int playCDtrack(int nTrack)
{
return 1;
}
void StartfadeCDaudio()
{
}
int StepFadeCDaudio()
{
return 0;
}
int CDplaying()
{
return 1;
}
void StopCD()
{
}

13
source/exhumed/src/cd.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef __cd_h__
#define __cd_h__
int initcdaudio();
void setCDaudiovolume(int val);
int playCDtrack(int nTrack);
void StartfadeCDaudio();
int StepFadeCDaudio();
int CDplaying();
void StopCD();
#endif

View file

@ -0,0 +1,25 @@
#include "cdaudio.h"
int fadecdaudio()
{
/* TODO
StartfadeCDaudio();
while (1)
{
if (!StepFadeCDaudio()) {
return 1;
}
else {
WaitTicks(1);
}
}
*/
return 1;
}
void CheckCD()
{
}

View file

@ -0,0 +1,8 @@
#ifndef __cdaudio_h__
#define __cdaudio_h__
void CheckCD();
int fadecdaudio();
#endif

View file

@ -0,0 +1,12 @@
#include "cdrom.h"
int checkcdrom()
{
return 1;
}
char GetCDDriveLetter()
{
return 'D';
}

View file

@ -0,0 +1,8 @@
#ifndef __cdrom_h__
#define __cdrom_h__
int checkcdrom();
char GetCDDriveLetter();
#endif

View file

@ -0,0 +1,632 @@
#include "compat.h"
#include "renderlayer.h"
#include "build.h"
#include "cache1d.h"
#include "keyboard.h"
#include "control.h"
#include "exhumed.h"
#include "typedefs.h"
#include "scriplib.h"
#include "config.h"
#include <string>
#include <io.h>
#include <stdio.h>
#include <time.h>
#define kMaxGameFunctions 40
#define kMaxGameFuncLen 64
// KEEPINSYNC mact/include/_control.h, build/src/sdlayer.cpp
#define MAXJOYBUTTONS 32
#define MAXJOYBUTTONSANDHATS (MAXJOYBUTTONS+4)
// KEEPINSYNC mact/include/_control.h, build/src/sdlayer.cpp
#define MAXMOUSEAXES 2
#define MAXMOUSEDIGITAL (MAXMOUSEAXES*2)
// KEEPINSYNC mact/include/_control.h, build/src/sdlayer.cpp
#define MAXJOYAXES 9
#define MAXJOYDIGITAL (MAXJOYAXES*2)
// default mouse scale
#define DEFAULTMOUSEANALOGUESCALE 65536
// default joystick settings
#if defined(GEKKO)
#define DEFAULTJOYSTICKANALOGUESCALE 16384
#define DEFAULTJOYSTICKANALOGUEDEAD 1000
#define DEFAULTJOYSTICKANALOGUESATURATE 9500
#else
#define DEFAULTJOYSTICKANALOGUESCALE 65536
#define DEFAULTJOYSTICKANALOGUEDEAD 2000
#define DEFAULTJOYSTICKANALOGUESATURATE 9500
#endif
static const char gamefunctions[kMaxGameFunctions][kMaxGameFuncLen] =
{
"Move_Forward",
"Move_Backward",
"Turn_Left",
"Turn_Right",
"Strafe",
"Strafe_Left",
"Strafe_Right",
"Run",
"Jump",
"Crouch",
"Fire",
"Open",
"Look_Up",
"Look_Down",
"Look_Straight",
"Aim_Up",
"Aim_Down",
"SendMessage",
"Weapon_1",
"Weapon_2",
"Weapon_3",
"Weapon_4",
"Weapon_5",
"Weapon_6",
"Weapon_7",
"Mouseview",
"Pause",
"Map",
"Zoom_In",
"Zoom_Out",
"Gamma_Correction",
"Escape",
"Shrink_Screen",
"Enlarge_Screen",
"Inventory",
"Inventory_Left",
"Inventory_Right",
"Mouse_Sensitivity_Up",
"Mouse_Sensitivity_Down"
"Show_Console",
};
static const char keydefaults[kMaxGameFunctions * 2][kMaxGameFuncLen] =
{
"Up", "Kpad8",
"Down", "Kpad2",
"Left", "Kpad4",
"Right", "KPad6",
"LAlt", "RAlt",
",", "",
".", "",
"LShift", "RShift",
"A", "",
"Z", "",
"LCtrl", "RCtrl",
"Space", "",
"PgUp", "",
"PgDn", "",
"Home", "",
"Insert", "",
"Delete", "",
"T", "",
"1", "",
"2", "",
"3", "",
"4", "",
"5", "",
"6", "",
"7", "",
"/", "",
"Pause", "",
"Tab", "",
"=", "",
"-", "",
"F11", "",
"Escape", "",
"Kpad-", "",
"Kpad+", "",
"Enter", "",
"[", "",
"]", "",
"F7", "",
"F8", "",
"`", "",
};
static const char *mousedefaults[MAXMOUSEBUTTONS] =
{
"Fire",
"Strafe",
"Move_Forward"
"",
"",
"",
};
static const char *mouseclickeddefaults[MAXMOUSEBUTTONS] =
{
};
static const char* mouseanalogdefaults[MAXMOUSEAXES] =
{
"analog_strafing",
"analog_moving",
};
static const char* mousedigitaldefaults[MAXMOUSEDIGITAL] =
{
};
ud_setup_t gSetup;
#define kMaxSetupFiles 20
#define kSetupFilename "SETUP.CFG"
static char setupfilename[128] = {kSetupFilename};
int lMouseSens = 32;
unsigned int dword_1B82E0 = 0;
int32_t FXVolume;
int32_t MusicVolume;
int32_t MixRate;
int32_t MidiPort;
int32_t NumVoices;
int32_t NumChannels;
int32_t NumBits;
int32_t ReverseStereo;
int32_t MusicDevice;
int32_t FXDevice;
int32_t ControllerType;
int32_t scripthandle;
int32_t setupread;
int32_t useprecache;
int32_t MouseDeadZone, MouseBias;
int32_t SmoothInput;
// JBF 20031211: Store the input settings because
// (currently) mact can't regurgitate them
int32_t MouseFunctions[MAXMOUSEBUTTONS][2];
int32_t MouseDigitalFunctions[MAXMOUSEAXES][2];
int32_t MouseAnalogueAxes[MAXMOUSEAXES];
int32_t MouseAnalogueScale[MAXMOUSEAXES];
int32_t JoystickFunctions[MAXJOYBUTTONSANDHATS][2];
int32_t JoystickDigitalFunctions[MAXJOYAXES][2];
int32_t JoystickAnalogueAxes[MAXJOYAXES];
int32_t JoystickAnalogueScale[MAXJOYAXES];
int32_t JoystickAnalogueInvert[MAXJOYAXES];
int32_t JoystickAnalogueDead[MAXJOYAXES];
int32_t JoystickAnalogueSaturate[MAXJOYAXES];
uint8_t KeyboardKeys[kMaxGameFunctions][2];
int32_t MAXCACHE1DSIZE = (96*1024*1024);
void SetupGameButtons()
{
CONTROL_DefineFlag(gamefunc_Move_Forward, FALSE);
CONTROL_DefineFlag(gamefunc_Move_Backward, FALSE);
CONTROL_DefineFlag(gamefunc_Turn_Left, FALSE);
CONTROL_DefineFlag(gamefunc_Turn_Right, FALSE);
CONTROL_DefineFlag(gamefunc_Strafe, FALSE);
CONTROL_DefineFlag(gamefunc_Strafe_Left, FALSE);
CONTROL_DefineFlag(gamefunc_Strafe_Right, FALSE);
CONTROL_DefineFlag(gamefunc_Jump, FALSE);
CONTROL_DefineFlag(gamefunc_Crouch, FALSE);
CONTROL_DefineFlag(gamefunc_Fire, FALSE);
CONTROL_DefineFlag(gamefunc_Open, FALSE);
CONTROL_DefineFlag(gamefunc_Aim_Up, FALSE);
CONTROL_DefineFlag(gamefunc_Aim_Down, FALSE);
CONTROL_DefineFlag(gamefunc_Look_Up, FALSE);
CONTROL_DefineFlag(gamefunc_Look_Down, FALSE);
CONTROL_DefineFlag(gamefunc_Look_Straight, FALSE);
CONTROL_DefineFlag(gamefunc_Run, FALSE);
CONTROL_DefineFlag(gamefunc_SendMessage, FALSE);
CONTROL_DefineFlag(gamefunc_Weapon_1, FALSE);
CONTROL_DefineFlag(gamefunc_Weapon_2, FALSE);
CONTROL_DefineFlag(gamefunc_Weapon_3, FALSE);
CONTROL_DefineFlag(gamefunc_Weapon_4, FALSE);
CONTROL_DefineFlag(gamefunc_Weapon_5, FALSE);
CONTROL_DefineFlag(gamefunc_Weapon_6, FALSE);
CONTROL_DefineFlag(gamefunc_Weapon_7, FALSE);
CONTROL_DefineFlag(gamefunc_Pause, FALSE);
CONTROL_DefineFlag(gamefunc_Map, FALSE);
CONTROL_DefineFlag(gamefunc_Gamma_Correction, FALSE);
CONTROL_DefineFlag(gamefunc_Escape, FALSE);
CONTROL_DefineFlag(gamefunc_Shrink_Screen, FALSE);
CONTROL_DefineFlag(gamefunc_Enlarge_Screen, FALSE);
CONTROL_DefineFlag(gamefunc_Zoom_In, FALSE);
CONTROL_DefineFlag(gamefunc_Zoom_Out, FALSE);
CONTROL_DefineFlag(gamefunc_Inventory_Left, FALSE);
CONTROL_DefineFlag(gamefunc_Inventory_Right, FALSE);
CONTROL_DefineFlag(gamefunc_Mouseview, FALSE);
CONTROL_DefineFlag(gamefunc_Inventory, FALSE);
CONTROL_DefineFlag(gamefunc_Mouse_Sensitivity_Up, FALSE);
CONTROL_DefineFlag(gamefunc_Mouse_Sensitivity_Down, FALSE);
}
hashtable_t h_gamefuncs = { kMaxGameFunctions<<1, NULL };
int32_t CONFIG_FunctionNameToNum(const char *func)
{
if (!func)
return -1;
return hash_findcase(&h_gamefuncs, func);
}
static char const * CONFIG_FunctionNumToName(int32_t func)
{
if ((unsigned)func >= (unsigned)kMaxGameFunctions)
return "";
return gamefunctions[func];
}
int32_t CONFIG_AnalogNameToNum(const char *func)
{
if (!func)
return -1;
else if (!Bstrcasecmp(func, "analog_turning"))
return analog_turning;
else if (!Bstrcasecmp(func, "analog_strafing"))
return analog_strafing;
else if (!Bstrcasecmp(func, "analog_moving"))
return analog_moving;
else if (!Bstrcasecmp(func, "analog_lookingupanddown"))
return analog_lookingupanddown;
else
return -1;
}
static char const * CONFIG_AnalogNumToName(int32_t func)
{
switch (func)
{
case analog_turning:
return "analog_turning";
case analog_strafing:
return "analog_strafing";
case analog_moving:
return "analog_moving";
case analog_lookingupanddown:
return "analog_lookingupanddown";
}
return "";
}
static void CONFIG_SetJoystickButtonFunction(int i, int j, int function)
{
JoystickFunctions[i][j] = function;
CONTROL_MapButton(function, i, j, controldevice_joystick);
}
static void CONFIG_SetJoystickAnalogAxisScale(int i, int scale)
{
JoystickAnalogueScale[i] = scale;
CONTROL_SetAnalogAxisScale(i, scale, controldevice_joystick);
}
static void CONFIG_SetJoystickAnalogAxisInvert(int i, int invert)
{
JoystickAnalogueInvert[i] = invert;
CONTROL_SetAnalogAxisInvert(i, invert, controldevice_joystick);
}
static void CONFIG_SetJoystickAnalogAxisDeadSaturate(int i, int dead, int saturate)
{
JoystickAnalogueDead[i] = dead;
JoystickAnalogueSaturate[i] = saturate;
joySetDeadZone(i, dead, saturate);
}
static void CONFIG_SetJoystickDigitalAxisFunction(int i, int j, int function)
{
JoystickDigitalFunctions[i][j] = function;
CONTROL_MapDigitalAxis(i, function, j, controldevice_joystick);
}
static void CONFIG_SetJoystickAnalogAxisFunction(int i, int function)
{
JoystickAnalogueAxes[i] = function;
CONTROL_MapAnalogAxis(i, function, controldevice_joystick);
}
void CONFIG_SetDefaultKeys(const char (*keyptr)[kMaxGameFunctions], bool lazy/*=false*/)
{
static char const s_gamefunc_[] = "gamefunc_";
int constexpr strlen_gamefunc_ = ARRAY_SIZE(s_gamefunc_) - 1;
if (!lazy)
{
Bmemset(KeyboardKeys, 0xff, sizeof(KeyboardKeys));
CONTROL_ClearAllBinds();
}
for (int i=0; i < ARRAY_SSIZE(gamefunctions); ++i)
{
if (gamefunctions[i][0] == '\0')
continue;
auto &key = KeyboardKeys[i];
int const default0 = KB_StringToScanCode(keyptr[i<<1]);
int const default1 = KB_StringToScanCode(keyptr[(i<<1)+1]);
// skip the function if the default key is already used
// or the function is assigned to another key
if (lazy && (key[0] != 0xff || (CONTROL_KeyIsBound(default0) && Bstrlen(CONTROL_KeyBinds[default0].cmdstr) > strlen_gamefunc_
&& CONFIG_FunctionNameToNum(CONTROL_KeyBinds[default0].cmdstr + strlen_gamefunc_) >= 0)))
{
#if 0 // defined(DEBUGGINGAIDS)
if (key[0] != 0xff)
initprintf("Skipping %s bound to %s\n", keyptr[i<<1], CONTROL_KeyBinds[default0].cmdstr);
#endif
continue;
}
key[0] = default0;
key[1] = default1;
if (key[0])
CONTROL_FreeKeyBind(key[0]);
if (key[1])
CONTROL_FreeKeyBind(key[1]);
if (i == gamefunc_Show_Console)
OSD_CaptureKey(key[0]);
else
CONFIG_MapKey(i, key[0], 0, key[1], 0);
}
}
void CONFIG_SetDefaults()
{
FXVolume = 128;
MusicVolume = 128;
ReverseStereo = 0;
ControllerType = controltype_keyboardandmouse;
lMouseSens = 8;
}
int CONFIG_ReadSetup()
{
char tempbuf[1024];
CONTROL_ClearAssignments();
CONFIG_SetDefaults();
setupread = 1;
pathsearchmode = 1;
if (scripthandle < 0)
{
if (buildvfs_exists(setupfilename)) // JBF 20031211
scripthandle = SCRIPT_Load(setupfilename);
else if (buildvfs_exists(kSetupFilename))
{
int const i = wm_ynbox("Import Configuration Settings",
"The configuration file \"%s\" was not found. "
"Import configuration data from \"%s\"?",
setupfilename, kSetupFilename);
if (i)
scripthandle = SCRIPT_Load(kSetupFilename);
}
}
pathsearchmode = 0;
if (scripthandle < 0)
return -1;
SCRIPT_GetNumber(scripthandle, "Setup", "ForceSetup", &gSetup.forcesetup);
SCRIPT_GetNumber(scripthandle, "Setup", "NoAutoLoad", &gSetup.noautoload);
int32_t cachesize;
SCRIPT_GetNumber(scripthandle, "Setup", "CacheSize", &cachesize);
if (cachesize > MAXCACHE1DSIZE)
MAXCACHE1DSIZE = cachesize;
// TODO:
if (/*g_noSetup == 0 && */g_modDir[0] == '/')
{
SCRIPT_GetString(scripthandle, "Setup","ModDir",&g_modDir[0]);
if (!buildvfs_isdir(g_modDir))
{
initprintf("Invalid mod dir in cfg!\n");
Bsprintf(g_modDir,"/");
}
}
windowx = -1;
windowy = -1;
SCRIPT_GetNumber(scripthandle, "Screen Setup", "MaxRefreshFreq", (int32_t *)&maxrefreshfreq);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenBPP", &gSetup.bpp);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenHeight", &gSetup.ydim);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenMode", &gSetup.fullscreen);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "ScreenWidth", &gSetup.xdim);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPosX", (int32_t *)&windowx);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPosY", (int32_t *)&windowy);
SCRIPT_GetNumber(scripthandle, "Screen Setup", "WindowPositioning", (int32_t *)&windowpos);
if (gSetup.bpp < 8) gSetup.bpp = 32;
setupread = 1;
}
void CONFIG_SetupMouse(void)
{
if (scripthandle < 0)
return;
char str[80];
char temp[80];
for (int i=0; i<MAXMOUSEBUTTONS; i++)
{
Bsprintf(str,"MouseButton%d",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
MouseFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
Bsprintf(str,"MouseButtonClicked%d",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
MouseFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
}
// map over the axes
for (int i=0; i<MAXMOUSEAXES; i++)
{
Bsprintf(str,"MouseAnalogAxes%d",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
MouseAnalogueAxes[i] = CONFIG_AnalogNameToNum(temp);
Bsprintf(str,"MouseDigitalAxes%d_0",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
MouseDigitalFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
Bsprintf(str,"MouseDigitalAxes%d_1",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
MouseDigitalFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
Bsprintf(str,"MouseAnalogScale%d",i);
int32_t scale = ud.config.MouseAnalogueScale[i];
SCRIPT_GetNumber(ud.config.scripthandle, "Controls", str, &scale);
ud.config.MouseAnalogueScale[i] = scale;
}
for (int i=0; i<MAXMOUSEBUTTONS; i++)
{
CONTROL_MapButton(ud.config.MouseFunctions[i][0], i, 0, controldevice_mouse);
CONTROL_MapButton(ud.config.MouseFunctions[i][1], i, 1, controldevice_mouse);
}
for (int i=0; i<MAXMOUSEAXES; i++)
{
CONTROL_MapAnalogAxis(i, ud.config.MouseAnalogueAxes[i], controldevice_mouse);
CONTROL_MapDigitalAxis(i, ud.config.MouseDigitalFunctions[i][0], 0,controldevice_mouse);
CONTROL_MapDigitalAxis(i, ud.config.MouseDigitalFunctions[i][1], 1,controldevice_mouse);
CONTROL_SetAnalogAxisScale(i, ud.config.MouseAnalogueScale[i], controldevice_mouse);
}
}
void CONFIG_SetupJoystick(void)
{
int32_t i;
char str[80];
char temp[80];
int32_t scale;
if (scripthandle < 0) return;
for (i=0; i<MAXJOYBUTTONSANDHATS; i++)
{
Bsprintf(str,"ControllerButton%d",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
ud.config.JoystickFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
Bsprintf(str,"ControllerButtonClicked%d",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle,"Controls", str,temp))
ud.config.JoystickFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
}
// map over the axes
for (i=0; i<MAXJOYAXES; i++)
{
Bsprintf(str,"ControllerAnalogAxes%d",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
JoystickAnalogueAxes[i] = CONFIG_AnalogNameToNum(temp);
Bsprintf(str,"ControllerDigitalAxes%d_0",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
JoystickDigitalFunctions[i][0] = CONFIG_FunctionNameToNum(temp);
Bsprintf(str,"ControllerDigitalAxes%d_1",i);
temp[0] = 0;
if (!SCRIPT_GetString(scripthandle, "Controls", str,temp))
ud.config.JoystickDigitalFunctions[i][1] = CONFIG_FunctionNameToNum(temp);
Bsprintf(str,"ControllerAnalogScale%d",i);
scale = ud.config.JoystickAnalogueScale[i];
SCRIPT_GetNumber(ud.config.scripthandle, "Controls", str,&scale);
ud.config.JoystickAnalogueScale[i] = scale;
Bsprintf(str,"ControllerAnalogInvert%d",i);
scale = ud.config.JoystickAnalogueInvert[i];
SCRIPT_GetNumber(ud.config.scripthandle, "Controls", str,&scale);
ud.config.JoystickAnalogueInvert[i] = scale;
Bsprintf(str,"ControllerAnalogDead%d",i);
scale = ud.config.JoystickAnalogueDead[i];
SCRIPT_GetNumber(ud.config.scripthandle, "Controls", str,&scale);
ud.config.JoystickAnalogueDead[i] = scale;
Bsprintf(str,"ControllerAnalogSaturate%d",i);
scale = ud.config.JoystickAnalogueSaturate[i];
SCRIPT_GetNumber(ud.config.scripthandle, "Controls", str,&scale);
ud.config.JoystickAnalogueSaturate[i] = scale;
}
for (i=0; i<MAXJOYBUTTONSANDHATS; i++)
{
CONTROL_MapButton(ud.config.JoystickFunctions[i][0], i, 0, controldevice_joystick);
CONTROL_MapButton(ud.config.JoystickFunctions[i][1], i, 1, controldevice_joystick);
}
for (i=0; i<MAXJOYAXES; i++)
{
CONTROL_MapAnalogAxis(i, ud.config.JoystickAnalogueAxes[i], controldevice_joystick);
CONTROL_MapDigitalAxis(i, ud.config.JoystickDigitalFunctions[i][0], 0, controldevice_joystick);
CONTROL_MapDigitalAxis(i, ud.config.JoystickDigitalFunctions[i][1], 1, controldevice_joystick);
CONTROL_SetAnalogAxisScale(i, ud.config.JoystickAnalogueScale[i], controldevice_joystick);
CONTROL_SetAnalogAxisInvert(i, ud.config.JoystickAnalogueInvert[i], controldevice_joystick);
}
}
void SetupInput()
{
if (CONTROL_Startup(controltype_keyboardandmouse, &BGetTime, kTimerTicks))
{
ERRprintf("There was an error initializing the CONTROL system.\n");
engineUnInit();
Bexit(5);
}
SetupGameButtons();
CONFIG_SetupMouse();
CONFIG_SetupJoystick();
CONTROL_JoystickEnabled = (gSetup.usejoystick && CONTROL_JoyPresent);
CONTROL_MouseEnabled = (gSetup.usemouse && CONTROL_MousePresent);
// JBF 20040215: evil and nasty place to do this, but joysticks are evil and nasty too
for (int i=0; i<joystick.numAxes; i++)
joySetDeadZone(i,JoystickAnalogueDead[i],JoystickAnalogueSaturate[i]);
}
void LoadConfig()
{
CONFIG_ReadSetup();
/*
Joy_x = 0;
Joy_y = 0;
Joy_xs = 1;
Joy_ys = 1;
Joy_xb = 2;
Joy_yb = 2;
*/
}

View file

@ -0,0 +1,71 @@
#ifndef __config_h__
#define __config_h__
enum {
gamefunc_Move_Forward, // 0
gamefunc_Move_Backward, // 1
gamefunc_Turn_Left,
gamefunc_Turn_Right,
gamefunc_Strafe,
gamefunc_Strafe_Left,
gamefunc_Strafe_Right,
gamefunc_Run, // 7
gamefunc_Jump, // 8
gamefunc_Crouch, // 9
gamefunc_Fire, // 10
gamefunc_Open, // 11
gamefunc_Look_Up, // 12
gamefunc_Look_Down,
gamefunc_Look_Straight,
gamefunc_Aim_Up,
gamefunc_Aim_Down,
gamefunc_SendMessage,
gamefunc_Weapon_1,
gamefunc_Weapon_2,
gamefunc_Weapon_3,
gamefunc_Weapon_4,
gamefunc_Weapon_5,
gamefunc_Weapon_6,
gamefunc_Weapon_7,
gamefunc_Mouseview,
gamefunc_Pause,
gamefunc_Map,
gamefunc_Zoom_In,
gamefunc_Zoom_Out,
gamefunc_Gamma_Correction,
gamefunc_Escape,
gamefunc_Shrink_Screen,
gamefunc_Enlarge_Screen,
gamefunc_Inventory,
gamefunc_Inventory_Left,
gamefunc_Inventory_Right,
gamefunc_Mouse_Sensitivity_Up,
gamefunc_Mouse_Sensitivity_Down,
gamefunc_Show_Console,
};
typedef struct {
int32_t usejoystick;
int32_t usemouse;
int32_t fullscreen;
int32_t xdim;
int32_t ydim;
int32_t bpp;
int32_t forcesetup;
int32_t noautoload;
} ud_setup_t;
void SetupInput();
void LoadConfig();
int CONFIG_ReadSetup();
extern int lMouseSens;
extern ud_setup_t gSetup;
extern int32_t MAXCACHE1DSIZE;
void CONFIG_MapKey(int which, kb_scancode key1, kb_scancode oldkey1, kb_scancode key2, kb_scancode oldkey2);
#endif

View file

@ -0,0 +1,36 @@
#ifndef __engine_h__
#define __engine_h__
#include "compat.h"
#include "build.h"
#include "pragmas.h"
#include "typedefs.h"
#define kMaxTiles 6144
#define kMaxSprites 4096
#define kMaxSectors 1024
#define kMaxWalls 8192
#define kMaxTiles 6144
#define kMaxVoxels 4096
enum
{
kStatIgnited = 404
};
#define kMaxSpritesOnscreen 1024
#define kMaxPalookups 256
#define kMaxStatus 1024
#define MAXPSKYTILES 256
inline long Sin(int angle)
{
return sintable[angle & 0x7FF];
}
int movesprite(short spritenum, long dx, long dy, long dz, long ceildist, long flordist, unsigned long clipmask);
void overwritesprite(long thex, long they, short tilenum, signed char shade, char stat, char dapalnum);
#endif

View file

@ -0,0 +1,111 @@
#include "engine.h"
#include <io.h>
#include <fcntl.h>
#include <malloc.h>
// static long globhiz, globloz, globhihit, globlohit;
void overwritesprite(long thex, long they, short tilenum, signed char shade, char stat, char dapalnum)
{
#if 0
rotatesprite(thex << 16, they << 16, 0x10000, (short)((flags & 8) << 7), tilenum, shade, dapalnum,
(char)(((flags & 1 ^ 1) << 4) + (flags & 2) + ((flags & 4) >> 2) + ((flags & 16) >> 2) ^ ((flags & 8) >> 1)),
windowx1, windowy1, windowx2, windowy2);
#endif
rotatesprite(thex << 16, they << 16, 65536L, (stat & 8) << 7, tilenum, shade, dapalnum,
(((stat & 1) ^ 1) << 4) + (stat & 2) + ((stat & 4) >> 2) + (((stat & 16) >> 2) ^ ((stat & 8) >> 1)),
windowxy1.x, windowxy1.y, windowxy2.x, windowxy2.y);
}
void permanentwritesprite(long thex, long they, short tilenum, signed char shade, long cx1, long cy1, long cx2, long cy2, char dapalnum)
{
rotatesprite(thex << 16, they << 16, 65536L, 0, tilenum, shade, dapalnum, 8 + 16, cx1, cy1, cx2, cy2);
}
void resettiming()
{
numframes = 0L;
totalclock = 0L;
// TODO totalclocklock = 0L;
}
void kensetpalette(unsigned char *vgapal)
{
//setbrightness(0, (char*)vgapal, 4 | 2);
// TODO
Bmemcpy(palette, vgapal, 768);
videoSetPalette(0, 0, 4 | 2);
#if 0
char vesapal[1024];
for(int i = 0; i < 256; i++)
{
vesapal[i*4+0] = vgapal[i*3+2];
vesapal[i*4+1] = vgapal[i*3+1];
vesapal[i*4+2] = vgapal[i*3+0];
vesapal[i*4+3] = 0;
}
#ifndef __WATCOMC__
(0L, 256L, vesapal);
#endif
#endif
}
void printext(long x, long y, char *buffer, short tilenum, char invisiblecol)
{
int i;
unsigned char ch;
for (i = 0; buffer[i] != 0; i++)
{
ch = (unsigned char)buffer[i];
rotatesprite((x - ((ch & 15) << 3)) << 16, (y - ((ch >> 4) << 3)) << 16, 65536L, 0, tilenum, 0, 0, 8 + 16 + 128, x, y, x + 7, y + 7);
x += 8;
}
#if 0
long i;
char ch;
for(i=0;buffer[i]!=0;i++)
{
ch = buffer[i];
rotatesprite((x-((8&15)<<3))<<16,(y-((8>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+64+128,x,y,x+7,y+7);
rotatesprite((x-((ch&15)<<3))<<16,(y-((ch>>4)<<3))<<16,65536L,0,tilenum,0,0,8+16+128,x,y,x+7,y+7);
x += 8;
}
#endif
}
void precache()
{
int i;
for (i = 0; i < numsectors; i++)
{
short j = sector[i].ceilingpicnum;
if (waloff[j] == 0) tileLoad(j);
j = sector[i].floorpicnum;
if (waloff[j] == 0) tileLoad(j);
}
for (i = 0; i < numwalls; i++)
{
short j = wall[i].picnum;
if (waloff[j] == 0) tileLoad(j);
}
for (i = 0; i < kMaxSprites; i++)
{
if (sprite[i].statnum < kMaxStatus)
{
short j = sprite[i].picnum;
if (waloff[j] == 0) tileLoad(j);
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,169 @@
#ifndef __exhumed_h__
#define __exhumed_h__
#define kTimerTicks 120
#ifdef __WATCOMC__
void handleevents();
#endif
void DebugOut(const char *fmt, ...);
void bail2dos(const char *fmt, ...);
int ExhumedMain(int argc, char *argv[]);
void FinishLevel();
void SetHiRes();
void BlackOut();
void DoGameOverScene();
int Query(short n, short l, ...);
extern unsigned char curpal[];
void TintPalette(int a, int b, int c);
void MySetPalette(unsigned char *palette);
void GetCurPal(unsigned char *palette);
void EraseScreen(int eax);
void RestorePalette();
int FindGString(const char *str);
void WaitTicks(int nTicks);
void FadeIn();
void FadeOut(int bFadeMusic);
int myprintext(int x, int y, const char *str, int shade);
int MyGetStringWidth(const char *str);
void mychangespritesect(int nSprite, int nSector);
void mydeletesprite(int nSprite);
void GrabPalette();
void mysetbrightness(char nBrightness);
void StartFadeIn();
int DoFadeIn();
void InitSpiritHead();
int CopyCharToBitmap(char nChar, int nTile, int xPos, int yPos);
// TODO - relocate
void StatusMessage(int messageTime, const char *fmt, ...);
int DoSpiritHead();
extern buildvfs_kfd kopen4loadfrommod(const char* filename, char searchfirst);
extern short nCDTrackLength;
extern char sHollyStr[];
extern int localclock;
extern int moveframes;
extern short bSerialPlay;
extern int nNetPlayerCount;
extern int htimer;
extern int nNetTime;
extern short barpages;
extern short nTotalPlayers;
extern short nFontFirstChar;
extern short nBackgroundPic;
extern short nShadowPic;
extern short nCreaturesLeft;
extern int lLocalButtons;
extern short nEnergyTowers;
extern short nEnergyChan;
extern short nSpiritSprite;
extern short bNoCDCheck;
extern short bInDemo;
extern short nFreeze;
extern short nCurBodyNum;
extern short nBodyTotal;
extern short bSnakeCam;
extern short levelnum;
extern short nScreenWidth;
extern short nScreenHeight;
extern short bMapMode;
extern short nButtonColor;
extern short nHeadStage;
extern short lastfps;
extern int flash;
extern short bNoCreatures;
extern short nLocalSpr;
extern short levelnew;
extern short textpages;
extern short nSnakeCam;
extern short bHiRes;
extern short bCoordinates;
extern short bFullScreen;
extern short bHolly;
extern short screensize;
extern int totalmoves;
extern short nGamma;
extern short screenpage;
extern int lCountDown;
extern short bSlipMode;
extern short nItemTextIndex;
extern const char *gString[];
extern char g_modDir[BMAX_PATH];
enum {
kPalNormal = 0,
kPalNoDim,
kPalTorch,
kPalNoTorch,
kPalBrite,
kPalRedBrite,
kPalGreenBrite,
kPalNormal2,
kPalNoDim2,
kPalTorch2,
kPalNoTorch2,
kPalBrite2
};
#endif

View file

@ -0,0 +1,424 @@
// Our replacement for the MACT scripting library as the one Exhumed/Powerslave uses is from an older version. This code is based on that older version
#include "typedefs.h"
#include "exscript.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#if 0
// 16 bytes in size?
struct Script
{
char * _0;
Script *_4;
Script * _8;
Script * _12;
};
int ScriptGrabbed = 0;
Script *currentsection = 0;
int scriptline = 0;
Script *script = 0;
BYTE *scriptbuffer = 0;
BYTE *script_p = 0;
BYTE *scriptend_p = 0;
int tokenready = 0;
char scriptfilename[128];
void FreeScriptSection()
{
}
void FreeScript()
{
}
void Error(const char *fmt, ...)
{
// TODO
exit(-1);
}
bool TokenAvailable(int nLine)
{
BYTE *pOffs = script_p;
if (pOffs >= scriptend_p) {
return false;
}
while (1)
{
char c = *pOffs;
if (c > ' ')
{
if (c != ';') {
return true;
}
while (1)
{
c = *pOffs;
if (c == 0xA) {
break;
}
if (pOffs >= scriptend_p) {
return 0;
}
pOffs++;
}
}
else
{
if (c == 0x0A && !nLine)
{
Error("Line %i is incomplete\nin file %s\n", scriptline, scriptfilename);
}
pOffs++;
if (pOffs >= scriptend_p) {
return false;
}
}
}
}
void CheckParseOverflow()
{
if (script_p >= scriptend_p) {
Error("End of script reached prematurely\n");
}
}
void SkipWhiteSpace(int nLine)
{
while (1)
{
CheckParseOverflow();
char c = *script_p;
if (c > ' ')
{
if (c != ';') {
return;
}
while (1)
{
c = *script_p;
if (c == 0xA || script_p >= scriptend_p) {
continue;
}
script_p++;
}
}
else
{
script_p++;
if (c != 0xA) {
continue;
}
if (!nLine)
{
Error("Line %i is incomplete\nin file %s\n");
}
scriptline++;
}
}
}
void AddScriptEntry(char *entry, Script *pScript)
{
Script *eax = 0;
if (!currentsection) {
Error("No current section adding %s", entry);
}
if (currentsection->_4->_8 != currentsection->_4)
{
while (1)
{
if (stricmp(entry, currentsection->_4->_8->_0) == 0)
{
eax = currentsection->_4->_8;
break;
}
if (currentsection->_4->_8->_8 == currentsection->_4)
{
break;
}
}
}
if (!eax)
{
Script *pScript = new Script;
Script *ecx = currentsection->_4;
pScript->_8 = currentsection->_4;
pScript->_12 = ecx->_12;
ecx = currentsection->_4;
ecx->_12->_8 = pScript;
currentsection->_4->_12 = pScript;
pScript->_0 = entry;
pScript->_4 = pScript;
}
else
{
eax = 0;
if (currentsection->_4->_8 != currentsection->_4)
{
while (1)
{
if (stricmp(entry, currentsection->_4->_8->_0) == 0)
{
eax = currentsection->_4->_8;
break;
}
if (currentsection->_4->_8->_8 == currentsection->_4) {
break;
}
}
}
eax->_0 = entry;
eax->_4 = pScript;
}
}
void AddScriptSection(char *section)
{
Script *eax = 0;
if (script->_8 != script)
{
while (1)
{
if (stricmp(section, script->_8->_0))
{
if (script->_8 == script) {
eax = 0;
break;
}
}
else {
eax = script->_8;
break;
}
}
}
if (!eax)
{
Script *pNew = new Script;
pNew->_8 = script;
Script *ebx = script->_12;
pNew->_12 = ebx;
ebx->_8 = pNew;
script->_12 = pNew;
pNew->_0 = section;
pNew->_4 = new Script;
pNew->_4->_12 = pNew->_4;
pNew->_4->_8 = pNew->_4;
}
eax = 0;
if (script->_8 != script)
{
while (1)
{
if (!stricmp(section, script->_8->_0))
{
eax = script->_8;
break;
}
if (script->_8->_8 == script)
{
break;
}
}
}
currentsection = eax;
}
void DecodeToken()
{
char c = *script_p;
if (c == '[')
{
char *pSection = (char*)script_p;
while (1)
{
c = *script_p;
if (c <= ' ' || c == '=') {
break;
}
script_p++;
CheckParseOverflow();
}
c = *script_p;
if (c != '=')
{
script_p = '\0';
SkipWhiteSpace(1);
c = *script_p;
if (c != '=')
{
Error("No entry separator found for %s\n", pSection);
}
script_p = '\0';
SkipWhiteSpace(1);
AddScriptEntry(pSection, script_p);
while (1)
{
}
}
}
else
{
script_p++;
char *pSection = (char*)script_p;
while (1)
{
c = *script_p;
if (c != ']')
{
if (c == 0xA) {
Error("No matching bracket found for section %s", pSection);
}
script_p++;
CheckParseOverflow();
}
else
{
script_p = '\0';
AddScriptSection(pSection);
while (1)
{
c = *script_p;
if (c == 0xA) {
return;
}
if (script_p >= scriptend_p) {
return;
}
script_p++;
}
}
}
}
}
void LoadScript(char *filename, int nVal)
{
if (!ScriptGrabbed) {
FreeScript();
}
script = new Script;
currentsection = 0;
script->_12 = script;
script->_8 = script;
int nScriptSize = 0;
// LoadFile(filename);
{
FILE *fp = fopen(filename, "rb");
if (!fp) {
// TODO - do error message
return;
}
fseek(fp, 0, SEEK_END);
nScriptSize = ftell(fp);
fseek(fp, 0, SEEK_SET);
scriptbuffer = new BYTE[nScriptSize];
if (!scriptbuffer) {
// TODO - do error message
return;
}
fread(scriptbuffer, 1, nScriptSize, fp);
fclose(fp);
}
strcpy(scriptfilename, filename);
scriptline = 1;
script_p = scriptbuffer;
tokenready = 0;
scriptend_p = scriptbuffer + nScriptSize;
int edx = 0;
if (nVal)
{
int nLine = 1;
while (1)
{
if (edx) {
return;
}
if (TokenAvailable(nLine))
{
SkipWhiteSpace(nLine);
DecodeToken();
}
else
{
edx = nLine;
}
}
}
}
#endif

View file

@ -0,0 +1,7 @@
#ifndef __exscript_h__
#define __exscript_h__
#endif

572
source/exhumed/src/fish.cpp Normal file
View file

@ -0,0 +1,572 @@
#include "fish.h"
#include "anims.h"
#include "engine.h"
#include "sequence.h"
#include "random.h"
#include "runlist.h"
#include "exhumed.h"
#include "move.h"
#include "trigdat.h"
#include "init.h"
#include <assert.h>
#define kMaxFishes 128
#define kMaxChunks 128
short FishSprite = -1;
short FishCount = 0;
static actionSeq ActionSeq[] = {
{8, 0},
{8, 0},
{0, 0},
{24, 0},
{8, 0},
{32, 1},
{33, 1},
{34, 1},
{35, 1},
{39, 1}
};
short nChunksFree;
int nFreeChunk[kMaxChunks] = { 0 };
struct Fish
{
short nHealth;
short field_2;
short nAction;
short nSprite;
short nTarget;
short field_A;
short field_C;
short field_E;
};
struct Chunk
{
short nSprite;
short field_2;
short field_4;
short field_6;
};
Fish FishList[kMaxFishes];
Chunk FishChunk[kMaxChunks];
void InitFishes()
{
FishCount = 0;
FishSprite = 1;
nChunksFree = kMaxChunks;
for (int i = 0; i < kMaxChunks; i++) {
nFreeChunk[i] = i;
}
}
int BuildFishLimb(short nFish, short edx)
{
if (nChunksFree <= 0) {
return -1;
}
short nSprite = FishList[nFish].nSprite;
nChunksFree--;
int nFree = nFreeChunk[nChunksFree];
int nSprite2 = insertsprite(sprite[nSprite].sectnum, 99);
assert(nSprite2 >= 0 && nSprite2 < kMaxSprites);
FishChunk[nFree].nSprite = nSprite2;
FishChunk[nFree].field_4 = edx + 40;
FishChunk[nFree].field_2 = RandomSize(3) % SeqSize[SeqOffsets[kSeqFish] + edx + 40];
sprite[nSprite2].x = sprite[nSprite].x;
sprite[nSprite2].y = sprite[nSprite].y;
sprite[nSprite2].z = sprite[nSprite].z;
sprite[nSprite2].cstat = 0;
sprite[nSprite2].shade = -12;
sprite[nSprite2].pal = 0;
sprite[nSprite2].xvel = (RandomSize(5) - 16) << 8;
sprite[nSprite2].yvel = (RandomSize(5) - 16) << 8;
sprite[nSprite2].xrepeat = 64;
sprite[nSprite2].yrepeat = 64;
sprite[nSprite2].xoffset = 0;
sprite[nSprite2].yoffset = 0;
sprite[nSprite2].zvel = (-(RandomByte() + 512)) * 2;
// not sure what's going on here... return value doesn't seem to be used
seq_GetSeqPicnum(kSeqFish, FishChunk[nFree].field_4, 0);
sprite[nSprite2].picnum = edx;
sprite[nSprite2].lotag = runlist_HeadRun() + 1;
sprite[nSprite2].clipdist = 0;
// GrabTimeSlot(3);
sprite[nSprite2].extra = -1;
sprite[nSprite2].owner = runlist_AddRunRec(sprite[nSprite2].lotag - 1, nFree | 0x200000);
sprite[nSprite2].hitag = runlist_AddRunRec(NewRun, nFree | 0x200000);
return nFree | 0x200000;
}
void BuildBlood(int x, int y, int z, short nSector)
{
BuildAnim(-1, kSeqFish, 36, x, y, z, nSector, 75, 128);
}
void FuncFishLimb(int a, int nDamage, int nRun)
{
short nFish = RunData[nRun].nVal;
short nSprite = FishChunk[nFish].nSprite;
assert(nSprite >= 0 && nSprite < kMaxSprites);
int nSeq = SeqOffsets[kSeqFish] + FishChunk[nFish].field_4;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
case 0x20000:
{
sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, FishChunk[nFish].field_2);
Gravity(nSprite);
FishChunk[nFish].field_2++;
if (FishChunk[nFish].field_2 >= SeqSize[nSeq])
{
FishChunk[nFish].field_2 = 0;
if (RandomBit()) {
BuildBlood(sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum);
}
}
int FloorZ = sector[sprite[nSprite].sectnum].floorz;
if (FloorZ <= sprite[nSprite].z)
{
sprite[nSprite].z += 256;
if ((sprite[nSprite].z - FloorZ) > 25600)
{
sprite[nSprite].zvel = 0;
runlist_DoSubRunRec(sprite[nSprite].owner);
runlist_FreeRun(sprite[nSprite].lotag - 1);
runlist_SubRunRec(sprite[nSprite].hitag);
mydeletesprite(nSprite);
}
else if ((sprite[nSprite].z - FloorZ) > 0)
{
sprite[nSprite].zvel = 1024;
}
return;
}
else
{
if (movesprite(nSprite, sprite[nSprite].xvel << 8, sprite[nSprite].yvel << 8, sprite[nSprite].zvel, 2560, -2560, CLIPMASK1))
{
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
}
}
return;
}
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, nSeq, FishChunk[nFish].field_2, 1);
return;
}
}
}
int BuildFish(int nSprite, int x, int y, int z, int nSector, int nAngle)
{
short nFish = FishCount;
FishCount++;
if (nFish >= kMaxFishes) {
return -1;
}
if (nSprite == -1)
{
nSprite = insertsprite(nSector, 103);
}
else
{
x = sprite[nSprite].x;
y = sprite[nSprite].y;
z = sprite[nSprite].z;
nAngle = sprite[nSprite].ang;
changespritestat(nSprite, 103);
}
assert(nSprite >= 0 && nSprite < kMaxSprites);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
sprite[nSprite].cstat = 0x101;
sprite[nSprite].shade = -12;
sprite[nSprite].clipdist = 80;
sprite[nSprite].xrepeat = 40;
sprite[nSprite].yrepeat = 40;
sprite[nSprite].pal = sector[sprite[nSprite].sectnum].ceilingpal;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].picnum = seq_GetSeqPicnum(kSeqFish, ActionSeq[0].a, 0);
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].ang = nAngle;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].hitag = 0;
sprite[nSprite].extra = -1;
// GrabTimeSlot(3);
FishList[nFish].nAction = 0;
FishList[nFish].nHealth = 200;
FishList[nFish].nSprite = nSprite;
FishList[nFish].nTarget = -1;
FishList[nFish].field_C = 60;
FishList[nFish].field_2 = 0;
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nFish | 0x120000);
FishList[nFish].field_E = runlist_AddRunRec(NewRun, nFish | 0x120000);
nCreaturesLeft++;
return nFish | 0x120000;
}
void IdleFish(short nFish, short edx)
{
short nSprite = FishList[nFish].nSprite;
short nAngle = sprite[nSprite].ang;
sprite[nSprite].ang += ((256 - RandomSize(9)) + 1024) & kAngleMask;
sprite[nSprite].xvel = (sprite[nSprite].ang + 512) >> 8;
sprite[nSprite].yvel = (sprite[nSprite].ang) >> 8;
FishList[nFish].nAction = 0;
FishList[nFish].field_2 = 0;
sprite[nSprite].zvel = RandomSize(9);
if (!edx)
{
if (RandomBit()) {
sprite[nSprite].zvel = -sprite[nSprite].zvel;
}
}
else if (edx < 0)
{
sprite[nSprite].zvel = -sprite[nSprite].zvel;
}
}
void DestroyFish(short nFish)
{
short nSprite = FishList[nFish].nSprite;
runlist_DoSubRunRec(sprite[nSprite].owner);
runlist_FreeRun(sprite[nSprite].lotag - 1);
runlist_SubRunRec(FishList[nFish].field_E);
mydeletesprite(nSprite);
}
void FuncFish(int a, int nDamage, int nRun)
{
short nFish = RunData[nRun].nVal;
assert(nFish >= 0 && nFish < kMaxFishes);
short nSprite = FishList[nFish].nSprite;
short nAction = FishList[nFish].nAction;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
default:
{
DebugOut("unknown msg %d for Fish\n", a & 0x7F0000);
return;
}
case 0xA0000:
{
if (FishList[nFish].nHealth <= 0) {
return;
}
else
{
nDamage = runlist_CheckRadialDamage(nSprite);
if (!nDamage) {
return;
}
else
{
FishList[nFish].field_C = 10;
}
}
// fall through
}
case 0x80000:
{
if (!nDamage) {
return;
}
FishList[nFish].nHealth -= nDamage;
if (FishList[nFish].nHealth <= 0)
{
FishList[nFish].nHealth = 0;
nCreaturesLeft--;
sprite[nSprite].cstat &= 0xFEFE;
if (nMessage == 0x80000)
{
for (int i = 0; i < 3; i++)
{
BuildFishLimb(nFish, i);
}
// TODO PlayFXAtXYZ(StaticSound[kSound40], sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum);
DestroyFish(nFish);
}
else
{
FishList[nFish].nAction = 9;
FishList[nFish].field_2 = 0;
}
return;
}
else
{
short nTarget = a & 0xFFFF;
if (nTarget >= 0 && sprite[nTarget].statnum < 199)
{
FishList[nFish].nTarget = nTarget;
}
FishList[nFish].nAction = 4;
FishList[nFish].field_2 = 0;
FishList[nFish].field_C += 10;
}
return;
}
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, SeqOffsets[kSeqFish] + ActionSeq[nAction].a, FishList[nFish].field_2, ActionSeq[nAction].b);
tsprite[a & 0xFFFF].owner = -1;
return;
}
case 0x20000:
{
if (!(SectFlag[sprite[nSprite].sectnum] & kSectUnderwater))
{
Gravity(nSprite);
}
short nSeq = SeqOffsets[kSeqFish] + ActionSeq[nAction].a;
sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, FishList[nFish].field_2);
seq_MoveSequence(nSprite, nSeq, FishList[nFish].field_2);
FishList[nFish].field_2++;
if (FishList[nFish].field_2 >= SeqSize[nSeq]) {
FishList[nFish].field_2 = 0;
}
short nTarget = FishList[nFish].nTarget;
switch (nAction)
{
default:
return;
case 0:
{
FishList[nFish].field_C--;
if (FishList[nFish].field_C <= 0)
{
nTarget = FindPlayer(nSprite, 60);
if (nTarget >= 0)
{
FishList[nFish].nTarget = nTarget;
FishList[nFish].nAction = 2;
FishList[nFish].field_2 = 0;
int nAngle = GetMyAngle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].z - sprite[nSprite].z);
sprite[nSprite].zvel = Sin(nAngle) >> 5;
FishList[nFish].field_C = RandomSize(6) + 90;
}
else
{
IdleFish(nFish, 0);
}
}
break;
}
case 1:
return;
case 2:
case 3:
{
FishList[nFish].field_C--;
if (FishList[nFish].field_C <= 0)
{
IdleFish(nFish, 0);
return;
}
else
{
PlotCourseToSprite(nSprite, nTarget);
int nHeight = GetSpriteHeight(nSprite) >> 1;
int z = sprite[nTarget].z - sprite[nSprite].z;
if (z < 0) {
z = -z;
}
if (z <= nHeight)
{
sprite[nSprite].xvel = (Sin(sprite[nSprite].ang + 512) >> 5) - (Sin(sprite[nSprite].ang + 512) >> 7);
sprite[nSprite].yvel = ((Sin(sprite[nSprite].ang) >> 5) >> 5) - ((Sin(sprite[nSprite].ang) >> 5) >> 7);
}
else
{
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
}
sprite[nSprite].zvel = (sprite[nTarget].z - sprite[nSprite].z) >> 3;
}
break;
}
case 4:
{
if (!FishList[nFish].field_2)
{
IdleFish(nFish, 0);
}
return;
}
case 8:
{
return;
}
case 9:
{
if (!FishList[nFish].field_2)
{
DestroyFish(nFish);
}
return;
}
}
int x = sprite[nSprite].x;
int y = sprite[nSprite].y;
int z = sprite[nSprite].z;
short nSector = sprite[nSprite].sectnum;
// loc_2EF54
int nVal = movesprite(nSprite, sprite[nSprite].xvel << 13, sprite[nSprite].yvel << 13, sprite[nSprite].zvel << 2, 0, 0, CLIPMASK0);
if (!(SectFlag[sprite[nSprite].sectnum] & kSectUnderwater))
{
mychangespritesect(nSprite, nSector);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
IdleFish(nFish, 0);
return;
}
else
{
if (nAction >= 5) {
return;
}
if (!nVal)
{
if (nAction == 3)
{
FishList[nFish].nAction = 2;
FishList[nFish].field_2 = 0;
}
return;
}
if (nVal != 0x30000)
{
if ((nVal & 0xC000) == 0x8000)
{
IdleFish(nFish, 0);
}
else if ((nVal & 0xC000) == 0xC000)
{
if (sprite[nVal & 0x3FFF].statnum == 100)
{
FishList[nFish].nTarget = nVal & 0x3FFF;
sprite[nSprite].ang = GetMyAngle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y);
if (nAction != 3)
{
FishList[nFish].nAction = 3;
FishList[nFish].field_2 = 0;
}
if (!FishList[nFish].field_2)
{
runlist_DamageEnemy(nTarget, nSprite, 2);
}
}
}
}
else if (nVal == 0x20000)
{
IdleFish(nFish, -1);
}
else
{
IdleFish(nFish, 1);
}
}
return;
}
}
}

11
source/exhumed/src/fish.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef __fish_h__
#define __fish_h__
void InitFishes();
int BuildFish(int nSprite, int x, int y, int z, int nSector, int nAngle);
void FuncFish(int, int, int);
void FuncFishLimb(int a, int b, int c);
#endif

View file

@ -0,0 +1,419 @@
#include "grenade.h"
#include "engine.h"
#include "player.h"
#include "runlist.h"
#include "exhumed.h"
#include "sound.h"
#include "move.h"
#include "init.h"
#include "bullet.h"
#include "gun.h"
#include "anims.h"
#include "lighting.h"
#include "sequence.h"
#include "random.h"
#include <assert.h>
int nGrenadeCount = 0;
int nGrenadesFree;
short GrenadeFree[kMaxGrenades];
struct Grenade
{
short field_0;
short field_2;
short nSprite;
short field_6;
short field_8;
short field_A;
short field_C;
short field_E;
int field_10;
int x;
int y;
};
Grenade GrenadeList[kMaxGrenades];
void InitGrenades()
{
nGrenadeCount = 0;
for (int i = 0; i < kMaxGrenades; i++) {
GrenadeFree[i] = i;
}
nGrenadesFree = kMaxGrenades;
}
short GrabGrenade()
{
return GrenadeFree[--nGrenadesFree];
}
void DestroyGrenade(short nGrenade)
{
runlist_DoSubRunRec(GrenadeList[nGrenade].field_6);
runlist_SubRunRec(GrenadeList[nGrenade].field_8);
runlist_DoSubRunRec(sprite[GrenadeList[nGrenade].nSprite].lotag - 1);
mydeletesprite(GrenadeList[nGrenade].nSprite);
GrenadeFree[nGrenadesFree] = nGrenade;
nGrenadesFree++;
}
void BounceGrenade(short nGrenade, short nAngle)
{
GrenadeList[nGrenade].field_10 >>= 1;
GrenadeList[nGrenade].x = (Sin(nAngle + 512) >> 5) * GrenadeList[nGrenade].field_10;
GrenadeList[nGrenade].y = (Sin(nAngle) >> 5) * GrenadeList[nGrenade].field_10;
D3PlayFX(StaticSound[kSound3], GrenadeList[nGrenade].nSprite);
}
int ThrowGrenade(short nPlayer, int edx, int ebx, int ecx, int push1)
{
if (nPlayerGrenade[nPlayer] < 0)
return -1;
short nGrenade = nPlayerGrenade[nPlayer];
short nGrenadeSprite = GrenadeList[nGrenade].nSprite;
short nPlayerSprite = PlayerList[nPlayer].nSprite;
mychangespritesect(nGrenadeSprite, nPlayerViewSect[nPlayer]);
short nAngle = sprite[nPlayerSprite].ang;
sprite[nGrenadeSprite].x = sprite[nPlayerSprite].x;
sprite[nGrenadeSprite].y = sprite[nPlayerSprite].y;
sprite[nGrenadeSprite].z = sprite[nPlayerSprite].z;
if (nAngle < 0) {
nAngle = sprite[nPlayerSprite].ang; // TODO - checkme
}
sprite[nGrenadeSprite].cstat &= 0x7FFF;
sprite[nGrenadeSprite].ang = nAngle;
if (push1 >= -3000)
{
int nVel = totalvel[nPlayer] << 5;
GrenadeList[nGrenade].field_10 = ((90 - GrenadeList[nGrenade].field_E) * (90 - GrenadeList[nGrenade].field_E)) + nVel;
sprite[nGrenadeSprite].zvel = (-64 * push1) - 4352;
int nMov = movesprite(nGrenadeSprite, Sin(nAngle + 512) * (sprite[nPlayerSprite].clipdist << 3), Sin(nAngle) * (sprite[nPlayerSprite].clipdist << 3), ecx, 0, 0, CLIPMASK1);
if (nMov & 0x8000)
{
nAngle = GetWallNormal(nMov & 0x3FFF);
BounceGrenade(nGrenade, nAngle);
}
}
else
{
GrenadeList[nGrenade].field_10 = 0;
sprite[nGrenadeSprite].zvel = sprite[nPlayerSprite].zvel;
}
GrenadeList[nGrenade].x = Sin(nAngle + 512) >> 4;
GrenadeList[nGrenade].x *= GrenadeList[nGrenade].field_10;
GrenadeList[nGrenade].y = Sin(nAngle) >> 4;
GrenadeList[nGrenade].y *= GrenadeList[nGrenade].field_10;
nPlayerGrenade[nPlayer] = -1;
return nGrenadeSprite;
}
int BuildGrenade(int nPlayer)
{
if (nGrenadesFree == 0)
return -1;
int nGrenade = GrabGrenade();
int nSprite = insertsprite(nPlayerViewSect[nPlayer], 201);
assert(nSprite >= 0 && nSprite < kMaxSprites);
int nPlayerSprite = PlayerList[nPlayer].nSprite;
sprite[nSprite].x = sprite[nPlayerSprite].x;
sprite[nSprite].y = sprite[nPlayerSprite].y;
sprite[nSprite].z = sprite[nPlayerSprite].z - 3840;
sprite[nSprite].shade = -64;
sprite[nSprite].xrepeat = 20;
sprite[nSprite].yrepeat = 20;
sprite[nSprite].cstat = 0x8000u;
sprite[nSprite].picnum = 1;
sprite[nSprite].pal = 0;
sprite[nSprite].clipdist = 30;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].ang = sprite[nPlayerSprite].ang;
sprite[nSprite].yvel = 0;
sprite[nSprite].owner = nPlayerSprite;
sprite[nSprite].xvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].hitag = 0;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].extra = -1;
// GrabTimeSlot(3);
GrenadeList[nGrenade].field_E = 90;
GrenadeList[nGrenade].field_2 = 0;
GrenadeList[nGrenade].field_0 = 16;
GrenadeList[nGrenade].field_10 = -1;
GrenadeList[nGrenade].nSprite = nSprite;
GrenadeList[nGrenade].field_A = 0;
GrenadeList[nGrenade].field_C = 0;
GrenadeList[nGrenade].field_6 = runlist_AddRunRec(sprite[nSprite].lotag - 1, nGrenade | 0x0F0000);
GrenadeList[nGrenade].field_8 = runlist_AddRunRec(NewRun, nGrenade | 0x0F0000);
nGrenadePlayer[nGrenade] = nPlayer;
nPlayerGrenade[nPlayer] = nGrenade;
return nSprite;
}
void ExplodeGrenade(short nGrenade)
{
int var_28, var_20;
short nPlayer = nGrenadePlayer[nGrenade];
int nGrenadeSprite = GrenadeList[nGrenade].nSprite;
short nGrenadeSect = sprite[nGrenadeSprite].sectnum;
GrenadeList[nGrenade].field_C = 1;
if (SectFlag[nGrenadeSect] & kSectUnderwater)
{
var_28 = 75;
var_20 = 60;
}
else
{
if (sprite[nGrenadeSprite].z < sector[nGrenadeSect].floorz)
{
var_20 = 200;
var_28 = 36;
// TODO MonoOut("GRENPOW\n");
}
else
{
var_28 = 34;
var_20 = 150;
// TODO MonoOut("GRENBOOM\n");
}
}
if (GrenadeList[nGrenade].field_10 < 0)
{
short nPlayerSprite = PlayerList[nPlayer].nSprite;
short nAngle = sprite[nPlayerSprite].ang;
sprite[nGrenadeSprite].z = sprite[nPlayerSprite].z;
sprite[nGrenadeSprite].x = (Sin(nAngle + 512) >> 5) + sprite[nPlayerSprite].x;
sprite[nGrenadeSprite].y = (Sin(nAngle) >> 5) + sprite[nPlayerSprite].y;
changespritesect(nGrenadeSprite, sprite[nPlayerSprite].sectnum);
if (!PlayerList[nPlayer].invincibility) {
PlayerList[nPlayer].nHealth = 1;
}
}
short nDamage = BulletInfo[kWeaponGrenade].nDamage;
if (nPlayerDouble[nPlayer] > 0) {
nDamage *= 2;
}
runlist_RadialDamageEnemy(nGrenadeSprite, nDamage, BulletInfo[kWeaponGrenade].field_10);
BuildAnim(-1, var_28, 0, sprite[nGrenadeSprite].x, sprite[nGrenadeSprite].y, sprite[nGrenadeSprite].z, sprite[nGrenadeSprite].sectnum, var_20, 4);
AddFlash(sprite[nGrenadeSprite].sectnum, sprite[nGrenadeSprite].x, sprite[nGrenadeSprite].y, sprite[nGrenadeSprite].z, 128);
nGrenadePlayer[nGrenade] = -1;
DestroyGrenade(nGrenade);
}
void FuncGrenade(int a, int nDamage, int nRun)
{
short nGrenade = RunData[nRun].nVal;
assert(nGrenade >= 0 && nGrenade < kMaxGrenades);
short nGrenadeSprite = GrenadeList[nGrenade].nSprite;
short nSeq;
if (GrenadeList[nGrenade].field_C)
{
nSeq = SeqOffsets[kSeqGrenBoom];
}
else
{
nSeq = SeqOffsets[kSeqGrenRoll] + GrenadeList[nGrenade].field_A;
}
int nMessage = a & 0x7F0000;
switch (nMessage)
{
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, nSeq, GrenadeList[nGrenade].field_2 >> 8, 1);
break;
}
default:
{
DebugOut("unknown msg %d for bullet\n", a & 0x7F0000); // TODO - change 'bullet' to 'grenade' ?
return;
}
case 0x20000:
{
seq_MoveSequence(nGrenadeSprite, nSeq, GrenadeList[nGrenade].field_2 >> 8);
sprite[nGrenadeSprite].picnum = seq_GetSeqPicnum2(nSeq, GrenadeList[nGrenade].field_2 >> 8);
GrenadeList[nGrenade].field_E--;
if (!GrenadeList[nGrenade].field_E)
{
short nPlayer = nGrenadePlayer[nGrenade];
if (GrenadeList[nGrenade].field_10 < 0)
{
PlayerList[nPlayer].field_3A = 0;
PlayerList[nPlayer].field_34 = 0;
if (PlayerList[nPlayer].nAmmo[kWeaponGrenade])
{
PlayerList[nPlayer].bIsFiring = kFalse;
}
else
{
SelectNewWeapon(nPlayer);
PlayerList[nPlayer].nCurrentWeapon = PlayerList[nPlayer].field_38;
PlayerList[nPlayer].field_38 = -1;
}
}
ExplodeGrenade(nGrenade);
return;
}
else
{
if (GrenadeList[nGrenade].field_10 < 0) {
return;
}
int ebp = (GrenadeList[nGrenade].field_2 + GrenadeList[nGrenade].field_0) >> 8;
GrenadeList[nGrenade].field_2 += GrenadeList[nGrenade].field_0;
if (ebp < 0)
{
GrenadeList[nGrenade].field_2 += SeqSize[nSeq] << 8;
}
else
{
if (ebp >= SeqSize[nSeq])
{
if (GrenadeList[nGrenade].field_C)
{
DestroyGrenade(nGrenade);
return;
}
else
{
GrenadeList[nGrenade].field_2 = GrenadeList[nGrenade].field_C;
}
}
}
if (GrenadeList[nGrenade].field_C) {
return;
}
int zVel = sprite[nGrenadeSprite].zvel;
Gravity(nGrenadeSprite);
int nMov = movesprite(nGrenadeSprite, GrenadeList[nGrenade].x, GrenadeList[nGrenade].y, sprite[nGrenadeSprite].zvel, sprite[nGrenadeSprite].clipdist >> 1, sprite[nGrenadeSprite].clipdist >> 1, CLIPMASK1);
if (!nMov)
return;
if (nMov & 0x20000)
{
if (zVel)
{
if (SectDamage[sprite[nGrenadeSprite].sectnum] > 0)
{
ExplodeGrenade(nGrenade);
return;
}
GrenadeList[nGrenade].field_0 = (uchar)totalmoves; // limit to 8bits?
D3PlayFX(StaticSound[kSound3], nGrenadeSprite);
sprite[nGrenadeSprite].zvel = -(zVel >> 1);
if (sprite[nGrenadeSprite].zvel > -1280)
{
D3PlayFX(StaticSound[kSound5], nGrenadeSprite);
GrenadeList[nGrenade].field_0 = 0;
GrenadeList[nGrenade].field_2 = 0;
sprite[nGrenadeSprite].zvel = 0;
GrenadeList[nGrenade].field_A = 1;
}
}
GrenadeList[nGrenade].field_0 = 255 - (RandomByte() * 2);
GrenadeList[nGrenade].x -= (GrenadeList[nGrenade].x >> 4);
GrenadeList[nGrenade].y -= (GrenadeList[nGrenade].y >> 4);
}
// loc_2CF60:
if ((nMov & 0xC000) >= 0x8000)
{
if ((nMov & 0xC000) <= 0x8000)
{
BounceGrenade(nGrenade, GetWallNormal(nMov & 0x3FFF));
}
else if ((nMov & 0xC000) == 0xC000)
{
BounceGrenade(nGrenade, sprite[nMov & 0x3FFF].ang);
}
}
GrenadeList[nGrenade].field_2 = 0;
return;
}
break;
}
case 0xA0000:
{
if (nGrenadeSprite != nRadialSpr && !GrenadeList[nGrenade].field_C)
{
if (runlist_CheckRadialDamage(nGrenadeSprite) > 280)
{
GrenadeList[nGrenade].field_E = RandomSize(4) + 1;
}
}
break;
}
}
}

View file

@ -0,0 +1,13 @@
#ifndef __grenade_h__
#define __grenade_h__
#define kMaxGrenades 50
void InitGrenades();
int BuildGrenade(int nPlayer);
void DestroyGrenade(short nGrenade);
int ThrowGrenade(short nPlayer, int edx, int ebx, int ecx, int push1);
void FuncGrenade(int, int, int);
#endif

1101
source/exhumed/src/gun.cpp Normal file

File diff suppressed because it is too large Load diff

49
source/exhumed/src/gun.h Normal file
View file

@ -0,0 +1,49 @@
#ifndef __gun_h__
#define __gun_h__
#include "sequence.h"
#define kMaxWeapons 7
enum
{
kWeaponSword = 0,
kWeaponPistol,
kWeaponM60,
kWeaponFlamer,
kWeaponGrenade,
kWeaponStaff,
kWeaponRing,
kWeaponMummified
};
struct Weapon
{
short nSeq;
short b[12]; // seq offsets?
short nAmmoType;
short c;
short d; // default or min ammo? or ammo used per 'shot' ?
short bFireUnderwater;
// short pad[15];
};
extern Weapon WeaponInfo[];
extern short nTemperature[];
void RestoreMinAmmo(short nPlayer);
void FillWeapons(short nPlayer);
void ResetPlayerWeapons(short nPlayer);
void InitWeapons();
void SetNewWeapon(short nPlayer, short nWeapon);
void SetNewWeaponImmediate(short nPlayer, short nWeapon);
void SetNewWeaponIfBetter(short nPlayer, short nWeapon);
void SelectNewWeapon(short nPlayer);
void StopFiringWeapon(short nPlayer);
void FireWeapon(short nPlayer);
void CheckClip(short nPlayer);
void MoveWeapons(short nPlayer);
void DrawWeapons();
#endif

1209
source/exhumed/src/init.cpp Normal file

File diff suppressed because it is too large Load diff

49
source/exhumed/src/init.h Normal file
View file

@ -0,0 +1,49 @@
#ifndef __init_h__
#define __init_h__
#include "typedefs.h"
#define kMap20 20
enum {
kSectUnderwater = 0x2000,
kSectLava = 0x4000,
};
extern int ototalclock;
extern int initx;
extern int inity;
extern int initz;
extern short inita;
extern short initsect;
extern short nCurChunkNum;
extern short nBodyGunSprite[50];
extern int movefifoend;
extern int movefifopos;
extern short nCurBodyGunNum;
void SnapSectors(short nSectorA, short nSectorB, short b);
extern short SectSound[];
extern short SectDamage[];
extern short SectSpeed[];
extern int SectBelow[];
extern short SectFlag[];
extern int SectDepth[];
extern short SectSoundSect[];
extern int SectAbove[];
BOOL LoadLevel(int nMap);
void InstallEngine();
void ResetEngine();
void RemoveEngine();
void LoadObjects();
int myloadconfig();
int mysaveconfig();
#endif

View file

@ -0,0 +1,253 @@
#include "input.h"
#include "engine.h"
#include "exhumed.h"
#include "player.h"
#include "serial.h"
#include "network.h"
#include "types.h"
#include "keyboard.h"
#include "control.h"
#include "config.h"
#include <string.h>
int nNetMoves = 0;
short nInputStack = 0;
short bStackNode[kMaxPlayers];
short nTypeStack[kMaxPlayers];
PlayerInput sPlayerInput[kMaxPlayers];
int *pStackPtr;
// (nInputStack * 32) - 11;
void PushInput(PlayerInput *pInput, int edx)
{
if (!bStackNode[edx])
{
// memcpy(sInputStack[nInputStack], pInput,
}
}
int PopInput()
{
if (!nInputStack)
return -1;
nInputStack--;
// TEMP
return 0;
}
void InitInput()
{
memset(nTypeStack, 0, sizeof(nTypeStack));
nInputStack = 0;
memset(bStackNode, 0, sizeof(bStackNode));
// pStackPtr = &sInputStack;
}
void ClearSpaceBar(short nPlayer)
{
sPlayerInput[nPlayer].buttons &= 0x0FB;
CONTROL_ClearButton(gamefunc_Open);
}
void GetLocalInput()
{
int ebx = 6;
int eax = 24;
int edx = -8;
uchar cl;
uint32 esi;
while (ebx >= 0)
{
if (eax <= 31)
{
esi = CONTROL_ButtonState1;
cl = eax;
}
else
{
esi = CONTROL_ButtonState2;
cl = edx;
}
if ((esi >> cl) & 1)
break;
eax--;
edx--;
ebx--;
}
ebx++;
if (PlayerList[nLocalPlayer].nHealth)
{
eax = (BUTTON(gamefunc_Crouch) << 4) | (BUTTON(gamefunc_Fire) << 3);
edx = BUTTON(gamefunc_Jump);
ebx <<= 13;
eax |= edx;
eax |= ebx;
lLocalButtons = eax;
}
else
{
lLocalButtons = 0;
}
lLocalButtons |= BUTTON(gamefunc_Open) << 2;
if (BUTTON(gamefunc_Open)) {
int breakme = 123;
}
// TODO ExecRecord(&sPlayerInput[nLocalPlayer], sizeof(PlayerInput));
}
void BackupInput()
{
}
void SendInput()
{
}
void LogoffPlayer(int nPlayer)
{
if (nPlayer == nLocalPlayer)
return;
if (PlayerList[nPlayer].someNetVal == -1)
return;
memset(&sPlayerInput[nPlayer], 0, sizeof(sPlayerInput));
sprite[nDoppleSprite[nPlayer]].cstat = 0x8000u;
sprite[nPlayerFloorSprite[nPlayer]].cstat = 0x8000u;
sprite[PlayerList[nPlayer].nSprite].cstat = 0x8000u;
PlayerList[nPlayer].someNetVal = -1;
StatusMessage(150, "Player %d has left the game", nPlayer);
// TODO ClearPlayerInput(&sPlayerInput[nPlayer]);
nNetPlayerCount--;
}
void UpdateInputs()
{
nNetMoveFrames = moveframes;
if (nNetPlayerCount)
{
if (bSerialPlay) {
UpdateSerialInputs();
}
else {
UpdateNetInputs();
}
nNetMoves++;
if (!nNetMoves) {
nNetMoves++;
}
}
}
/*
ClearSpaceBar_
GetLocalInput_
GetModemInput_
BackupInput_
SendInput_
SendToUnAckd_
LogoffPlayer_
UpdateInputs_
faketimerhandler_
*/
void ClearAllKeys()
{
KB_ClearKeysDown();
KB_FlushKeyboardQueue();
}
void WaitNoKey(int nSecs, void (*pFunc) (void))
{
int nTotalTime = (kTimerTicks * nSecs) + totalclock;
while (nTotalTime > totalclock)
{
#ifdef _MSC_VER
handleevents();
#endif
if (pFunc) {
pFunc();
}
}
}
int WaitAnyKey(int nSecs)
{
int nTotalTime = totalclock + (kTimerTicks * nSecs);
while (1)
{
#ifdef _MSC_VER
handleevents();
#endif
if (nTotalTime <= totalclock || nSecs == -1) {
return -1;
}
int i = 0;
do
{
if (KB_KeyDown[i])
{
KB_KeyDown[i] = 0;
return i;
}
i++;
} while (i < 106);
}
}
/*
Name: _nLocalPlayer
Name: _nNetPlayerCount
Name: _nModemPlayer
Name: _nNetMoves
Name: _lLocalButtons
Name: _lLocalCodes
Name: _nInputStack
Name: _bSyncNet
Name: _lStartupTime
Name: _bStackNode
Name: _sSync
Name: _nTypeStack
Name: _sPlayerInput
Name: _pStackPtr
Name: _sInputStack
*/

View file

@ -0,0 +1,47 @@
#ifndef __input_h__
#define __input_h__
#include "typedefs.h"
enum {
kButtonJump = 0x1,
kButtonOpen = 0x4,
kButtonFire = 0x8,
kButtonCrouch = 0x10,
kButtonCheatGuns = 0x20,
kButtonCheatGodMode = 0x40,
kButtonCheatKeys = 0x80,
kButtonCheatItems = 0x100,
};
// 32 bytes
struct PlayerInput
{
int xVel;
int yVel;
short nAngle;
ushort buttons;
short nTarget;
schar horizon;
schar nItem;
int h;
char i;
char field_15[11];
};
void InitInput();
void ClearAllKeys();
void WaitNoKey(int nSecs, void (*pFunc) (void));
int WaitAnyKey(int nSecs);
void UpdateInputs();
void ClearSpaceBar(short nPlayer);
void GetLocalInput();
extern PlayerInput sPlayerInput[];
extern int nNetMoves;
#endif

View file

@ -0,0 +1,477 @@
#include "items.h"
#include "anims.h"
#include "player.h"
#include "exhumed.h"
#include "lighting.h"
#include "sound.h"
#include "status.h"
#include "engine.h"
#include "random.h"
#include "init.h"
#include "input.h"
#include "object.h"
struct AnimInfo
{
short a;
short repeat;
};
AnimInfo nItemAnimInfo[] = {
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ 6, 64 },
{ -1, 48 },
{ 0, 64 },
{ 1, 64 },
{ -1, 32 },
{ 4, 64 },
{ 5, 64 },
{ 16, 64 },
{ 10, 64 },
{ -1, 32 },
{ 8, 64 },
{ 9, 64 },
{ -1, 40 },
{ -1, 32 },
{ 7, 64 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ 14, 64 },
{ 15, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ 17, 48 },
{ 18, 48 },
{ 19, 48 },
{ 20, 48 },
{ 24, 64 },
{ 21, 64 },
{ 23, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ 11, 30 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 },
{ -1, 32 }
};
short nItemMagic[] = { 500, 1000, 100, 500, 400, 200, 700, 0 };
/*
short something
short x/y repeat
*/
short nRegenerates;
short nFirstRegenerate;
short nMagicCount;
void BuildItemAnim(short nSprite)
{
int nItem = sprite[nSprite].statnum - 906;
if (nItemAnimInfo[nItem].a >= 0)
{
int nAnim = BuildAnim(nSprite, 41, nItemAnimInfo[nItem].a, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, nItemAnimInfo[nItem].repeat, 20);
int nAnimSprite = GetAnimSprite(nAnim);
if (nItem == 44) {
sprite[nAnimSprite].cstat |= 2;
}
changespritestat(nAnimSprite, sprite[nSprite].statnum);
sprite[nAnimSprite].owner = nAnim;
sprite[nAnimSprite].hitag = sprite[nSprite].hitag;
}
else
{
sprite[nSprite].owner = -1;
sprite[nSprite].yrepeat = nItemAnimInfo[nItem].repeat;
sprite[nSprite].xrepeat = nItemAnimInfo[nItem].repeat;
}
}
void DestroyItemAnim(short nSprite)
{
short nAnim = sprite[nSprite].owner;
if (nAnim >= 0) {
DestroyAnim(nAnim);
}
}
void ItemFlash()
{
TintPalette(4, 4, 4);
}
void FillItems(short nPlayer)
{
for (int i = 0; i < 6; i++)
{
PlayerList[nPlayer].items[i] = 5;
}
PlayerList[nPlayer].nMagic = 1000;
if (nPlayer == nLocalPlayer)
{
ItemFlash();
SetMagicFrame();
}
if (nPlayerItem[nPlayer] == -1) {
SetPlayerItem(nPlayer, 0);
}
}
void UseEye(short nPlayer)
{
if (nPlayerInvisible[nPlayer] >= 0) {
nPlayerInvisible[nPlayer] = 900;
}
int nSprite = PlayerList[nPlayer].nSprite;
sprite[nSprite].cstat |= 0x8000;
if (nPlayerFloorSprite[nPlayer] >= 0) {
sprite[nSprite].cstat |= 0x8000;
}
if (nPlayer == nLocalPlayer)
{
ItemFlash();
D3PlayFX(StaticSound[kSound31], nSprite);
}
}
void UseMask(short nPlayer)
{
PlayerList[nPlayer].nMaskAmount = 1350;
PlayerList[nPlayer].nAir = 100;
if (nPlayer == nLocalPlayer)
{
SetAirFrame();
D3PlayFX(StaticSound[kSound31], PlayerList[nPlayer].nSprite);
}
}
void UseTorch(short nPlayer)
{
if (!nPlayerTorch[nPlayer]) {
SetTorch(nPlayer, 1);
}
nPlayerTorch[nPlayer] = 900;
}
void UseHeart(short nPlayer)
{
if (PlayerList[nPlayer].nHealth < kMaxHealth) {
PlayerList[nPlayer].nHealth = kMaxHealth;
}
if (nPlayer == nLocalPlayer)
{
ItemFlash();
SetHealthFrame(1);
D3PlayFX(StaticSound[kSound31], PlayerList[nPlayer].nSprite);
}
}
// invincibility
void UseScarab(short nPlayer)
{
if (PlayerList[nPlayer].invincibility < 900) {
PlayerList[nPlayer].invincibility = 900;
}
if (nPlayer == nLocalPlayer)
{
ItemFlash();
D3PlayFX(StaticSound[kSound31], PlayerList[nPlayer].nSprite);
}
}
// faster firing
void UseHand(short nPlayer)
{
nPlayerDouble[nPlayer] = 1350;
if (nPlayer == nLocalPlayer)
{
ItemFlash();
D3PlayFX(StaticSound[kSound31], PlayerList[nPlayer].nSprite);
}
}
void UseItem(short nPlayer, short nItem)
{
switch (nItem)
{
case 0:
UseHeart(nPlayer);
break;
case 1:
UseScarab(nPlayer);
break;
case 2:
UseTorch(nPlayer);
break;
case 3:
UseHand(nPlayer);
break;
case 4:
UseEye(nPlayer);
break;
case 5:
UseMask(nPlayer);
break;
default:
break;
}
PlayerList[nPlayer].items[nItem]--;
int nItemCount = PlayerList[nPlayer].items[nItem];
int nMagic = nItemMagic[nItem];
if (nPlayer == nLocalPlayer)
{
BuildStatusAnim(nItemCount * 2 + 156, 0);
}
if (!nItemCount)
{
for (nItem = 0; nItem < 6; nItem++)
{
if (PlayerList[nPlayer].items[nItem] > 0) {
break;
}
}
if (nItem == 6) {
nItem = -1;
}
}
PlayerList[nPlayer].nMagic -= nMagic;
SetPlayerItem(nPlayer, nItem);
if (nPlayer == nLocalPlayer) {
SetMagicFrame();
}
}
void UseCurItem(short nPlayer)
{
int nItem = nPlayerItem[nPlayer];
if (nItem >= 0)
{
if (PlayerList[nPlayer].items[nItem] > 0)
{
if (nItemMagic[nItem] <= PlayerList[nPlayer].nMagic)
{
sPlayerInput[nPlayer].nItem = nItem;
}
}
}
}
// TODO - bool return type?
int GrabItem(short nPlayer, short nItem)
{
if (PlayerList[nPlayer].items[nItem] >= 5) {
return 0;
}
PlayerList[nPlayer].items[nItem]++;
if (nPlayerItem[nPlayer] < 0 || nItem == nPlayerItem[nPlayer]) {
SetPlayerItem(nPlayer, nItem);
}
return 1;
}
void DropMagic(short nSprite)
{
if (lFinaleStart) {
return;
}
nMagicCount--;
if (nMagicCount <= 0)
{
int nAnim = BuildAnim(
-1,
64,
0,
sprite[nSprite].x,
sprite[nSprite].y,
sprite[nSprite].z,
sprite[nSprite].sectnum,
48,
4);
int nAnimSprite = GetAnimSprite(nAnim);
sprite[nAnimSprite].owner = nAnim;
AddFlash(sprite[nAnimSprite].sectnum, sprite[nAnimSprite].x, sprite[nAnimSprite].y, sprite[nAnimSprite].z, 128);
changespritestat(nAnimSprite, 950);
nMagicCount = RandomSize(2);
}
}
void InitItems()
{
nRegenerates = 0;
nFirstRegenerate = -1;
nMagicCount = 0;
}
void StartRegenerate(short nSprite)
{
SPRITE *pSprite = &sprite[nSprite];
int edi = -1;
int nReg = nFirstRegenerate;
int i = 0;
// for (int i = 0; i < nRegenerates; i++)
while (1)
{
if (i >= nRegenerates)
{
// ?? CHECKME
pSprite->xvel = pSprite->xrepeat;
pSprite->zvel = pSprite->shade;
pSprite->yvel = pSprite->pal;
break;
}
else
{
if (nReg != nSprite)
{
edi = nReg;
nReg = sprite[nReg].ang;
i++;
continue;
}
else
{
if (edi == -1)
{
nFirstRegenerate = pSprite->ang;
}
else
{
sprite[edi].ang = sprite[nSprite].ang;
}
nRegenerates--;
}
}
}
pSprite->extra = 1350;
pSprite->ang = nFirstRegenerate;
if (levelnum <= kMap20)
{
pSprite->ang /= 5;
}
pSprite->cstat = 0x8000;
pSprite->xrepeat = 1;
pSprite->yrepeat = 1;
pSprite->pal = 1;
nRegenerates++;
nFirstRegenerate = nSprite;
}
void DoRegenerates()
{
int nSprite = nFirstRegenerate;
for (int i = nRegenerates; i > 0; i--, nSprite = sprite[nSprite].ang)
{
if (sprite[nSprite].extra > 0)
{
sprite[nSprite].extra--;
if (sprite[nSprite].extra <= 0)
{
BuildAnim(-1, 38, 0, sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z, sprite[nSprite].sectnum, 64, 4);
D3PlayFX(StaticSound[kSoundTorchOn], i);
}
}
else
{
if (sprite[nSprite].xrepeat < sprite[nSprite].xvel)
{
sprite[nSprite].xrepeat += 2;
sprite[nSprite].yrepeat += 2;
continue;
}
}
sprite[nSprite].zvel = 0;
sprite[nSprite].yrepeat = sprite[nSprite].xvel;
sprite[nSprite].xrepeat = sprite[nSprite].xvel;
sprite[nSprite].pal = sprite[nSprite].yvel;
sprite[nSprite].yvel = sprite[nSprite].zvel; // setting to 0
sprite[nSprite].xvel = sprite[nSprite].zvel; // setting to 0
nRegenerates--;
if (sprite[nSprite].statnum == kStatExplodeTrigger) {
sprite[nSprite].cstat = 0x101;
}
else {
sprite[nSprite].cstat = 0;
}
if (nRegenerates == 0) {
nFirstRegenerate = -1;
}
}
}

View file

@ -0,0 +1,35 @@
#ifndef __items_h__
#define __items_h__
enum
{
kItemHeart = 0,
kItemInvincibility,
kItemTorch,
kItemDoubleDamage,
kItemInvisibility,
kItemMask,
};
extern short nItemMagic[];
void BuildItemAnim(short nSprite);
void DestroyItemAnim(short nSprite);
void ItemFlash();
void FillItems(short nPlayer);
void UseEye(short nPlayer);
void UseMask(short nPlayer);
void UseTorch(short nPlayer);
void UseHeart(short nPlayer);
void UseScarab(short nPlayer);
void UseHand(short nPlayer);
void UseItem(short nPlayer, short nItem);
void UseCurItem(short nPlayer);
int GrabItem(short nPlayer, short nItem);
void DropMagic(short nSprite);
void InitItems();
void StartRegenerate(short nSprite);
void DoRegenerates();
#endif

View file

@ -0,0 +1,499 @@
#include "engine.h"
#include "lavadude.h"
#include "random.h"
#include "runlist.h"
#include "sequence.h"
#include "exhumed.h"
#include "move.h"
#include "trigdat.h"
#include "move.h"
#include "bullet.h"
#include "sound.h"
#include <assert.h>
#define kMaxLavas 20
struct Lava
{
short nSprite;
short field_2;
short nAction;
short nTarget;
short nHealth;
short field_10;
short field_12;
};
Lava LavaList[kMaxLavas];
short LavaCount = 0;
short LavaSprite = -1;
static actionSeq ActionSeq[] = {
{0, 1},
{0, 1},
{1, 0},
{10, 0},
{19, 0},
{28, 1},
{29, 1},
{33, 0},
{42, 1}
};
// done
void InitLava()
{
LavaCount = 0;
LavaSprite = 1;
}
int BuildLavaLimb(int nSprite, int edx, int ebx)
{
short nSector = sprite[nSprite].sectnum;
int nLimbSprite = insertsprite(nSector, 118);
assert(nLimbSprite >= 0 && nLimbSprite < kMaxSprites);
sprite[nLimbSprite].x = sprite[nSprite].x;
sprite[nLimbSprite].y = sprite[nSprite].y;
sprite[nLimbSprite].z = sprite[nSprite].z - RandomLong() % ebx;
sprite[nLimbSprite].cstat = 0;
sprite[nLimbSprite].shade = -127;
sprite[nLimbSprite].pal = 1;
sprite[nLimbSprite].xvel = (RandomSize(5) - 16) << 8;
sprite[nLimbSprite].yvel = (RandomSize(5) - 16) << 8;
sprite[nLimbSprite].zvel = 2560 - (RandomSize(5) << 8);
sprite[nLimbSprite].yoffset = 0;
sprite[nLimbSprite].xoffset = 0;
sprite[nLimbSprite].xrepeat = 90;
sprite[nLimbSprite].yrepeat = 90;
sprite[nLimbSprite].picnum = (edx & 3) % 3;
sprite[nLimbSprite].hitag = 0;
sprite[nLimbSprite].lotag = runlist_HeadRun() + 1;
sprite[nLimbSprite].clipdist = 0;
// GrabTimeSlot(3);
sprite[nLimbSprite].extra = -1;
sprite[nLimbSprite].owner = runlist_AddRunRec(sprite[nLimbSprite].lotag - 1, nLimbSprite | 0x160000);
sprite[nLimbSprite].hitag = runlist_AddRunRec(NewRun, nLimbSprite | 0x160000);
return nLimbSprite;
}
void FuncLavaLimb(int eax, int ebx, int nRun)
{
short nSprite = RunData[nRun].nVal;
assert(nSprite >= 0 && nSprite < kMaxSprites);
int nMessage = eax & 0x7F0000;
switch (nMessage)
{
case 0x20000:
{
sprite[nSprite].shade += 3;
int nRet = movesprite(nSprite, sprite[nSprite].xvel << 12, sprite[nSprite].yvel << 12, sprite[nSprite].zvel, 2560, -2560, CLIPMASK1);
if (nRet || sprite[nSprite].shade > 100)
{
sprite[nSprite].zvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
runlist_DoSubRunRec(sprite[nSprite].owner);
runlist_FreeRun(sprite[nSprite].lotag - 1);
runlist_SubRunRec(sprite[nSprite].hitag);
mydeletesprite(nSprite);
}
break;
}
case 0x90000:
{
seq_PlotSequence(eax, (SeqOffsets[kSeqLavag] + 30) + sprite[nSprite].picnum, 0, 1);
break;
}
default:
return;
}
}
int BuildLava(short nSprite, int x, int y, int z, short nSector, short nAngle, int lastArg)
{
short nLava = LavaCount;
LavaCount++;
if (nLava >= kMaxLavas) {
return -1;
}
if (nSprite == -1)
{
nSprite = insertsprite(nSector, 118);
}
else
{
nSector = sprite[nSprite].sectnum;
nAngle = sprite[nSprite].ang;
x = sprite[nSprite].x;
y = sprite[nSprite].y;
changespritestat(nSprite, 118);
}
assert(nSprite >= 0 && nSprite < kMaxSprites);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = sector[nSector].floorz;
sprite[nSprite].cstat = 0x8000u;
sprite[nSprite].xrepeat = 200;
sprite[nSprite].yrepeat = 200;
sprite[nSprite].shade = -12;
sprite[nSprite].pal = 0;
sprite[nSprite].clipdist = 127;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].picnum = seq_GetSeqPicnum(kSeqLavag, ActionSeq[3].a, 0);
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].ang = nAngle;
sprite[nSprite].hitag = 0;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
// GrabTimeSlot(3);
sprite[nSprite].extra = -1;
LavaList[nLava].nAction = 0;
LavaList[nLava].nHealth = 4000;
LavaList[nLava].nSprite = nSprite;
LavaList[nLava].nTarget = -1;
LavaList[nLava].field_12 = lastArg;
LavaList[nLava].field_10 = 0;
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nLava | 0x150000);
LavaList[nLava].field_2 = runlist_AddRunRec(NewRun, nLava | 0x150000);
nCreaturesLeft++;
return nLava | 0x150000;
}
void FuncLava(int a, int nDamage, int nRun)
{
short nLava = RunData[nRun].nVal;
assert(nLava >= 0 && nLava < kMaxLavas);
short nAction = LavaList[nLava].nAction;
short nSeq = ActionSeq[nAction].a + SeqOffsets[kSeqLavag];
short nSprite = LavaList[nLava].nSprite;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
default:
{
DebugOut("unknown msg %d for Lava\n", a & 0x7F0000);
return;
}
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, nSeq, LavaList[nLava].field_10, ActionSeq[nAction].b);
tsprite[a & 0xFFFF].owner = -1;
return;
}
case 0xA0000:
{
return;
}
case 0x80000:
{
if (!nDamage) {
return;
}
LavaList[nLava].nHealth -= nDamage;
if (LavaList[nLava].nHealth <= 0)
{
LavaList[nLava].nHealth = 0;
LavaList[nLava].nAction = 5;
LavaList[nLava].field_10 = 0;
nCreaturesLeft--;
sprite[nSprite].cstat &= 0xFEFE;
}
else
{
short nTarget = a & 0xFFFF;
if (nTarget >= 0)
{
if (sprite[nTarget].statnum < 199)
{
LavaList[nLava].nTarget = nTarget;
}
}
if (nAction == 3)
{
if (!RandomSize(2))
{
LavaList[nLava].nAction = 4;
LavaList[nLava].field_10 = 0;
sprite[nSprite].cstat = 0;
}
}
BuildLavaLimb(nSprite, totalmoves, 0xFA00);
}
return;
}
case 0x20000:
{
sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, LavaList[nLava].field_10);
int var_38 = LavaList[nLava].field_10;
short nFlag = FrameFlag[SeqBase[nSeq] + var_38];
int var_1C;
if (nAction)
{
seq_MoveSequence(nSprite, nSeq, var_38);
LavaList[nLava].field_10++;
if (LavaList[nLava].field_10 >= SeqSize[nSeq])
{
var_1C = 1;
LavaList[nLava].field_10 = 0;
}
else
{
var_1C = 0;
}
}
short nTarget = LavaList[nLava].nTarget;
if (nTarget >= 0 && nAction < 4)
{
if (!(sprite[nTarget].cstat & 0x101) || sprite[nTarget].sectnum >= 1024)
{
nTarget = -1;
LavaList[nLava].nTarget = -1;
}
}
switch (nAction)
{
case 0:
{
if ((nLava & 0x1F) == (totalmoves & 0x1F))
{
if (nTarget < 0)
{
nTarget = FindPlayer(nSprite, 76800);
}
PlotCourseToSprite(nSprite, nTarget);
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512);
sprite[nSprite].yvel = Sin(sprite[nSprite].ang);
if (nTarget >= 0 && !RandomSize(1))
{
LavaList[nLava].nTarget = nTarget;
LavaList[nLava].nAction = 2;
sprite[nSprite].cstat = 0x101;
LavaList[nLava].field_10 = 0;
break;
}
}
int x = sprite[nSprite].x;
int y = sprite[nSprite].y;
int z = sprite[nSprite].z;
short nSector = sprite[nSprite].sectnum;
int nVal = movesprite(nSprite, sprite[nSprite].xvel << 8, sprite[nSprite].yvel << 8, 0, 0, 0, CLIPMASK0);
if (nSector != sprite[nSprite].sectnum)
{
changespritesect(nSprite, nSector);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
sprite[nSprite].ang = (sprite[nSprite].ang + ((RandomWord() & 0x3FF) + 1024)) & 0x7FF;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512);
sprite[nSprite].yvel = Sin(sprite[nSprite].ang);
break;
}
if (!nVal) {
break;
}
if ((nVal & 0x0C000) == 0x8000)
{
sprite[nSprite].ang = (sprite[nSprite].ang + ((RandomWord() & 0x3FF) + 1024)) & 0x7FF;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512);
sprite[nSprite].yvel = Sin(sprite[nSprite].ang);
break;
}
else if ((nVal & 0x0C000) == 0x0C000)
{
if ((nVal & 0x3FFF) == nTarget)
{
int nAng = getangle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y);
if (AngleDiff(sprite[nSprite].ang, nAng) < 64)
{
LavaList[nLava].nAction = 2;
sprite[nSprite].cstat = 0x101;
LavaList[nLava].field_10 = 0;
break;
}
}
}
break;
}
case 1:
case 6:
{
break;
}
case 2:
{
if (var_1C)
{
LavaList[nLava].nAction = 3;
LavaList[nLava].field_10 = 0;
PlotCourseToSprite(nSprite, nTarget);
sprite[nSprite].cstat |= 0x101;
}
break;
}
case 3:
{
if (nFlag & 0x80 && nTarget > -1)
{
int nHeight = GetSpriteHeight(nSprite);
GetUpAngle(nSprite, 0x0FFFF0600, nTarget, (-(nHeight >> 1)));
BuildBullet(nSprite, 10, Sin(sprite[nSprite].ang + 512) << 8, Sin(sprite[nSprite].ang) << 8, -1, sprite[nSprite].ang, nTarget + 10000, 1);
break;
}
else if (var_1C)
{
PlotCourseToSprite(nSprite, nTarget);
LavaList[nLava].nAction = 7;
LavaList[nLava].field_10 = 0;
break;
}
}
case 4:
{
if (var_1C)
{
LavaList[nLava].nAction = 7;
sprite[nSprite].cstat &= 0xFEFE;
}
break;
}
case 5:
{
if (nFlag & 0x40)
{
int nLimbSprite = BuildLavaLimb(nSprite, LavaList[nLava].field_10, 0xFA00u);
D3PlayFX(StaticSound[kSound26], nLimbSprite);
}
if (LavaList[nLava].field_10)
{
if (nFlag & 0x80)
{
int ecx = 0;
do
{
BuildLavaLimb(nSprite, ecx, 0xFA00u);
ecx++;
}
while (ecx < 20);
runlist_ChangeChannel(LavaList[nLava].field_12, 1);
}
}
else
{
int ecx = 0;
do
{
BuildLavaLimb(nSprite, ecx, 256);
ecx++;
}
while (ecx < 30);
runlist_DoSubRunRec(sprite[nSprite].owner);
runlist_FreeRun(sprite[nSprite].lotag - 1);
runlist_SubRunRec(LavaList[nLava].field_2);
mydeletesprite(nSprite);
}
break;
}
case 7:
{
if (var_1C)
{
LavaList[nLava].nAction = 8;
LavaList[nLava].field_10 = 0;
}
break;
}
case 8:
{
if (var_1C)
{
LavaList[nLava].nAction = 0;
LavaList[nLava].field_10 = 0;
sprite[nSprite].cstat = 0x8000;
}
break;
}
}
// loc_31521:
sprite[nSprite].pal = 1;
}
}
}

View file

@ -0,0 +1,11 @@
#ifndef __lavadude_h__
#define __lavadude_h__
void InitLava();
int BuildLava(short nSprite, int x, int y, int z, short nSector, short nAngle, int lastArg);
int BuildLavaLimb(int nSprite, int edx, int ebx);
void FuncLavaLimb(int, int, int);
void FuncLava(int, int, int);
#endif

View file

@ -0,0 +1,598 @@
#include "light.h"
#include "engine.h"
#include "exhumed.h"
#include "view.h"
#include "cd.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#ifdef __WATCOMC__
#include <dos.h>
#include <conio.h>
#include <i86.h>
void handleevents()
{
}
#else
#ifdef __cplusplus
extern "C" {
#endif
int handleevents(void);
#ifdef __cplusplus
}
#endif
#endif
#define kMaxGrads 12
char *GradList[kMaxGrads] = {
"normal.rmp",
"nodim.rmp",
"torch.rmp",
"notorch.rmp",
"brite.rmp",
"redbrite.rmp",
"grnbrite.rmp",
"normal.rmp",
"nodim.rmp",
"torch.rmp",
"notorch.rmp",
"brite.rmp"
};
int rtint = 0;
int gtint = 0;
int btint = 0;
char *origpalookup[kMaxPalookups];
unsigned char curpal[768];
unsigned char kenpal[768];
unsigned char *fadedestpal;
unsigned char *fadecurpal;
short nPalDelay;
short nPalDiff;
short overscanindex;
// keep a local copy of the palette that would have been sent to the VGA display adapter
uchar vgaPalette[768];
void MyLoadPalette()
{
int hFile = kopen4load("PALETTE.DAT", 1);
if (hFile == -1)
{
printf("Error reading palette 'PALETTE.DAT'\n");
return;
}
kread(hFile, kenpal, sizeof(kenpal));
kclose(hFile);
SetOverscan(kenpal);
}
int LoadPaletteLookups()
{
free(palookup[0]);
palookup[0] = NULL;
numpalookups = 64;
for (int i = 0; i < kMaxGrads; i++)
{
int hFile = kopen4load(GradList[i], 1);
if (hFile == -1)
{
printf("Error reading palette lookup '%s'\n", GradList[i]);
return 0;
}
makepalookup(i, NULL, 0, 0, 0, 0);
kread(hFile, palookup[i], 16384);
kclose(hFile);
origpalookup[i] = palookup[i];
}
return 1;
}
void SetGreenPal()
{
for (int i = 0; i < 12; i++)
{
palookup[i] = palookup[6];
}
palookup[5] = origpalookup[5];
}
void RestoreGreenPal()
{
for (int i = 0; i < 12; i++)
{
palookup[i] = origpalookup[i];
}
}
void WaitVBL()
{
#ifdef __WATCOMC__
while (!(inp(0x3da) & 8));
#endif
}
void MySetPalette(unsigned char *palette)
{
WaitVBL();
#ifdef __WATCOMC__
outp(0x3C8, 0);
int i;
for (i = 0; i < 768; i++)
{
outp(0x3C9, *palette);
palette++;
}
#else
// TODO
kensetpalette(palette);
memcpy(vgaPalette, palette, sizeof(vgaPalette));
#endif
}
void GetCurPal(unsigned char *palette)
{
#ifdef __WATCOMC__
if (!palette) {
palette = curpal;
}
outp(0x3C7, 0);
int i;
for (i = 0; i < 256; i++)
{
*palette = inp(0x3C9);
palette++;
*palette = inp(0x3C9);
palette++;
*palette = inp(0x3C9);
palette++;
}
#else
if (!palette) {
memcpy(curpal, vgaPalette, sizeof(curpal));
}
else {
memcpy(palette, vgaPalette, sizeof(curpal));
}
#endif
}
void GrabPalette()
{
SetOverscan(kenpal);
memcpy(curpal, kenpal, sizeof(curpal));
MySetPalette(kenpal);
nPalDiff = 0;
nPalDelay = 0;
btint = 0;
gtint = 0;
rtint = 0;
}
void BlackOut()
{
memset(curpal, 0, sizeof(curpal));
MySetPalette(curpal);
}
void RestorePalette()
{
memcpy(curpal, kenpal, sizeof(curpal));
MySetPalette(curpal);
}
void WaitTicks(int nTicks)
{
if (htimer)
{
nTicks += totalclock;
while (nTicks > totalclock) { handleevents(); }
}
else
{
while (nTicks > 0) {
nTicks--;
WaitVBL();
}
}
}
// unused
void DoFadeToRed()
{
for (int i = 0; i < 256; i += 3)
{
if (curpal[i + 1] > 0)
{
curpal[i + 1]--;
}
if (curpal[i + 2] > 0)
{
curpal[i + 1]--;
}
}
MySetPalette(curpal);
}
void FadeToWhite()
{
int ebx = 0;
for (int i = 0; i < 64; i++)
{
uchar *pPal = curpal;
for (int j = 0; j < 256; j++)
{
for (int k = 0; k < 3; k++)
{
if (*pPal < 63)
{
(*pPal)++;
ebx++;
}
pPal++;
}
}
MySetPalette(curpal);
WaitTicks(2);
// need to page flip in each iteration of the loop for non DOS version
nextpage();
if (!ebx) {
return;
}
}
}
void FadeOut(int bFadeMusic)
{
if (bFadeMusic) {
StartfadeCDaudio();
}
for (int i = 64; i > 0; i--)
{
int v4 = 0;
for (int j = 0; j < 768; j++)
{
if (curpal[j] > 0)
{
curpal[j]--;
v4++;
}
}
MySetPalette(curpal);
WaitTicks(2);
// need to page flip in each iteration of the loop for non DOS version
nextpage();
if (v4 == 0) {
break;
}
if (bFadeMusic) {
StepFadeCDaudio();
}
}
if (bFadeMusic) {
while (StepFadeCDaudio() != 0) {}
}
EraseScreen(overscanindex);
}
void StartFadeIn()
{
fadedestpal = kenpal;
fadecurpal = curpal;
}
int DoFadeIn()
{
int v2 = 0;
for (int i = 0; i < 768; i++)
{
v2++;
if (fadecurpal[i] < fadedestpal[i])
{
fadecurpal[i]++;
}
else
{
if (fadecurpal[i] == fadedestpal[i])
{
v2--;
}
else {
fadecurpal[i]--;
}
}
}
MySetPalette(fadecurpal);
return v2;
}
void FadeIn()
{
StartFadeIn();
while (1)
{
int val = DoFadeIn();
WaitTicks(2);
// need to page flip in each iteration of the loop for non DOS version
nextpage();
if (!val) {
break;
}
}
}
void FixPalette()
{
if (!nPalDiff) {
return;
}
if (nPalDelay > 0)
{
nPalDelay--;
return;
}
nPalDelay = 5;
for (int i = 0; i < 768; i++)
{
short nVal = curpal[i] - kenpal[i];
if (nVal > 0)
{
if (nVal > 5)
{
curpal[i] -= 5;
}
else
{
curpal[i] = kenpal[i];
}
}
}
nPalDiff -= 5;
gtint -= 5;
rtint -= 5;
if (gtint < 0) {
gtint = 0;
}
if (rtint < 0) {
rtint = 0;
}
if (nPalDiff < 0) {
nPalDiff = 0;
}
MySetPalette(curpal);
}
void TintPalette(int r, int g, int b)
{
int r2 = r;
int g2 = g;
int b2 = b;
uchar *pPal = curpal;
if (bCamera) {
return;
}
// range limit R between 5 and 63 if positive
if (r > 63)
{
r = 63;
}
else
{
if (r && r < 5) {
r = 5;
}
}
// range limit G between 5 and 63 if positive
if (g > 63)
{
g = 63;
}
else
{
if (g && g < 5) {
g = 5;
}
}
// range limit B between 5 and 63 if positive
if (b > 63)
{
b = 63;
}
else
{
if (b && b < 5) {
b = 5;
}
}
// loc_17EFA
if (g && gtint > 8) {
return;
}
gtint += g;
if (r && rtint > 64) {
return;
}
rtint += r;
// do not modify r, g or b variables from this point on
r2 = r;
g2 = g;
b2 = b;
if (r2 < 0) {
r2 = -r2;
}
// loc_17F3A
if (g2 < 0) {
g2 = -g2;
}
int nVal;
// loc_17F49
if (r2 > g2) {
nVal = r;
}
else {
nVal = g;
}
if (nVal < 0) {
nVal = -nVal;
}
if (b2 < 0) {
b2 = -b2;
}
if (nVal > b2) {
nVal = b2;
}
else {
if (b < 0) {
nVal = -b;
}
}
nPalDiff += nVal;
for (int i = 0; i < 256; i++)
{
*pPal += r;
if (*pPal > 63) {
*pPal = 63;
}
pPal++;
*pPal += g;
if (*pPal > 63) {
*pPal = 63;
}
pPal++;
*pPal += b;
if (*pPal > 63) {
*pPal = 63;
}
pPal++;
}
nPalDelay = 0;
}
void DoOverscanSet(short someval)
{
#ifdef __WATCOMC__
union REGS regs;
regs.h.al = 1;
regs.h.ah = 0x10;
regs.h.ch = someval;
int386(0x10, &regs, &regs);
#endif
}
// unused
void SetWhiteOverscan()
{
}
void SetOverscan(unsigned char *palette)
{
int edi = 1000;
overscanindex = 0;
for (int i = 0; i < 256; i++)
{
int ebx = 0;
for (int j = 0; j < 3; j++)
{
uchar cl = *palette;
palette++;
ebx += cl;
}
if (ebx < edi)
{
edi = ebx;
overscanindex = i;
}
}
DoOverscanSet(overscanindex);
}

View file

@ -0,0 +1,23 @@
#ifndef __light_h__
#define __light_h__
void MyLoadPalette();
int LoadPaletteLookups();
void WaitVBL();
void SetGreenPal();
void RestoreGreenPal();
void FixPalette();
void FadeToWhite();
extern void DoOverscanSet(short someval);
void SetOverscan(unsigned char *palette);
extern unsigned char kenpal[];
extern short overscanindex;
extern char *origpalookup[];
extern short nPalDiff;
#endif

View file

@ -0,0 +1,761 @@
#include "typedefs.h"
#include "lighting.h"
#include "player.h"
#include "engine.h"
#include "exhumed.h"
#include "sound.h"
#include "light.h"
#include "random.h"
#include <string.h>
#include <assert.h>
#define kMaxFlashes 2000
#define kMaxFlickerMask 25
#define kMaxGlows 50
#define kMaxFlickers 100
#define kMaxFlows 375
struct Flash
{
char field_0;
short field_1;
schar shade;
};
struct Glow
{
short field_0;
short field_2;
short nSector;
short field_6;
};
struct Flicker
{
short field_0;
short nSector;
unsigned int field_4;
};
struct Flow
{
short field_0;
short field_2;
int field_4;
int field_8;
int field_C;
int field_10;
int field_14;
int field_18;
};
Flash sFlash[kMaxFlashes];
Glow sGlow[kMaxGlows];
short nNextFlash[kMaxFlashes];
Flicker sFlicker[kMaxFlickers];
short nFreeFlash[kMaxFlashes];
Flow sFlowInfo[kMaxFlows];
int flickermask[kMaxFlickerMask];
short bTorch = 0;
short nFirstFlash = -1;
short nLastFlash = -1;
short nFlashDepth = 2;
short nFlashes;
short nFlowCount;
short nFlickerCount;
short nGlowCount;
int bDoFlicks = 0;
int bDoGlows = 0;
// done
int GrabFlash()
{
if (nFlashes >= kMaxFlashes) {
return -1;
}
short nFlash = nFreeFlash[nFlashes];
nNextFlash[nFlash] = -1;
nFlashes++;
if (nLastFlash <= -1)
{
nFirstFlash = nFlash;
}
else
{
nNextFlash[nLastFlash] = nFlash;
}
nLastFlash = nFlash;
return nLastFlash;
}
void InitLights()
{
int i;
nFlickerCount = 0;
for (i = 0; i < kMaxFlickerMask; i++) {
flickermask[i] = RandomSize(0x1F) * 2;
}
nGlowCount = 0;
nFlowCount = 0;
nFlashes = 0;
bDoFlicks = kFalse;
bDoGlows = kFalse;
for (i = 0; i < kMaxFlashes; i++) {
nFreeFlash[i] = i;
}
nFirstFlash = -1;
nLastFlash = -1;
}
void AddFlash(short nSector, int x, int y, int z, int val)
{
assert(nSector >= 0 && nSector < kMaxSectors);
int var_28 = 0;
unsigned int var_1C = val >> 8;
if (var_1C >= nFlashDepth) {
return;
}
unsigned int var_20 = val & 0x80;
unsigned int var_18 = val & 0x40;
val = ((var_1C + 1) << 8) | char(val);
int var_14 = 0;
short startwall = sector[nSector].wallptr;
short endwall = sector[nSector].wallptr + sector[nSector].wallnum;
for (int i = startwall; i < endwall; i++)
{
short wall2 = wall[i].point2;
int xAverage = (wall[i].x + wall[wall2].x) / 2;
int yAverage = (wall[i].y + wall[wall2].y) / 2;
SECTOR *pNextSector = NULL;
if (wall[i].nextsector > -1) {
pNextSector = &sector[wall[i].nextsector];
}
int ebx = -255;
if (!var_18)
{
int x2 = x - xAverage;
if (x2 < 0) {
x2 = -x2;
}
ebx = x2;
int y2 = y - yAverage;
if (y2 < 0) {
y2 = -y2;
}
ebx = ((y2 + ebx) >> 4) - 255;
}
if (ebx < 0)
{
var_14++;
var_28 += ebx;
if (wall[i].pal < 5)
{
if (!pNextSector || pNextSector->floorz < sector[nSector].floorz)
{
short nFlash = GrabFlash();
if (nFlash < 0) {
return;
}
sFlash[nFlash].field_0 = var_20 | 2;
sFlash[nFlash].shade = wall[i].shade;
sFlash[nFlash].field_1 = i;
wall[i].pal += 7;
ebx += wall[i].shade;
int eax = ebx;
if (ebx < -127) {
eax = -127;
}
wall[i].shade = eax;
if (!var_1C && !wall[i].overpicnum && pNextSector)
{
AddFlash(wall[i].nextsector, x, y, z, val);
}
}
}
}
}
if (var_14 && sector[nSector].floorpal < 4)
{
short nFlash = GrabFlash();
if (nFlash < 0) {
return;
}
sFlash[nFlash].field_0 = var_20 | 1;
sFlash[nFlash].field_1 = nSector;
sFlash[nFlash].shade = sector[nSector].floorshade;
sector[nSector].floorpal += 7;
int edx = sector[nSector].floorshade + var_28;
int eax = edx;
if (edx < -127) {
eax = -127;
}
sector[nSector].floorshade = eax;
if (!(sector[nSector].ceilingstat & 1))
{
if (sector[nSector].ceilingpal < 4)
{
short nFlash2 = GrabFlash();
if (nFlash2 >= 0)
{
sFlash[nFlash2].field_0 = var_20 | 3;
sFlash[nFlash2].field_1 = nSector;
sFlash[nFlash2].shade = sector[nSector].ceilingshade;
sector[nSector].ceilingpal += 7;
int edx = sector[nSector].ceilingshade + var_28;
int eax = edx;
if (edx < -127) {
eax = -127;
}
sector[nSector].ceilingshade = eax;
}
}
}
for (short nSprite = headspritesect[nSector]; nSprite >= 0; nSprite = nextspritesect[nSprite])
{
if (sprite[nSprite].pal < 4)
{
short nFlash3 = GrabFlash();
if (nFlash3 >= 0)
{
sFlash[nFlash3].field_0 = var_20 | 4;
sFlash[nFlash3].shade = sprite[nSprite].shade;
sFlash[nFlash3].field_1 = nSprite;
sprite[nSprite].pal += 7;
int eax = -255;
if (!var_18)
{
int xDiff = x - sprite[nSprite].x;
if (xDiff < 0) {
xDiff = -xDiff;
}
int yDiff = y - sprite[nSprite].y;
if (yDiff < 0) {
yDiff = -yDiff;
}
eax = ((xDiff + yDiff) >> 4) - 255;
}
if (eax < 0)
{
short shade = sprite[nSprite].shade + eax;
if (shade < -127) {
shade = -127;
}
sprite[nSprite].shade = shade;
}
}
}
}
}
}
void UndoFlashes()
{
if (!nFlashes) {
return;
}
int var_24 = 0; // CHECKME - Watcom error "initializer for variable var_24 may not execute
int edi = -1;
for (short nFlash = nFirstFlash; nFlash >= 0; nFlash = nNextFlash[nFlash])
{
assert(nFlash < 2000 && nFlash >= 0);
uchar var_28 = sFlash[nFlash].field_0 & 0x3F;
short nIndex = sFlash[nFlash].field_1;
if (sFlash[nFlash].field_0 & 0x80)
{
int var_20 = var_28 - 1;
assert(var_20 >= 0);
schar *pShade = NULL;
switch (var_20)
{
case 0:
{
assert(nIndex >= 0 && nIndex < kMaxSectors);
pShade = &sector[nIndex].floorshade;
break;
}
case 1:
{
assert(nIndex >= 0 && nIndex < kMaxWalls);
pShade = &wall[nIndex].shade;
break;
}
case 2:
{
assert(nIndex >= 0 && nIndex < kMaxSectors);
pShade = &sector[nIndex].ceilingshade;
break;
}
case 3:
{
assert(nIndex >= 0 && nIndex < kMaxSprites);
if (sprite[nIndex].pal >= 7)
{
pShade = &sprite[nIndex].shade;
}
else {
goto loc_1868A;
}
break;
}
default:
break;
}
assert(pShade != NULL);
short var_2C = (*pShade) + 6;
int var_30 = sFlash[nFlash].shade;
if (var_2C < var_30)
{
*pShade = var_2C;
edi = nFlash;
continue;
}
}
// loc_185FE
var_24 = var_28 - 1; // CHECKME - Watcom error "initializer for variable var_24 may not execute
assert(var_24 >= 0);
switch (var_24)
{
default:
break;
case 0:
{
sector[nIndex].floorpal -= 7;
sector[nIndex].floorshade = sFlash[nFlash].shade;
break;
}
case 1:
{
wall[nIndex].pal -= 7;
wall[nIndex].shade = sFlash[nFlash].shade;
break;
}
case 2:
{
sector[nIndex].ceilingpal -= 7;
sector[nIndex].ceilingshade = sFlash[nFlash].shade;
break;
}
case 3:
{
if (sprite[nIndex].pal >= 7)
{
sprite[nIndex].pal -= 7;
sprite[nIndex].shade = sFlash[nFlash].shade;
}
break;
}
}
loc_1868A:
nFlashes--;
assert(nFlashes >= 0);
nFreeFlash[nFlashes] = nFlash;
if (edi != -1)
{
nNextFlash[edi] = nNextFlash[nFlash];
}
if (nFlash == nFirstFlash)
{
nFirstFlash = nNextFlash[nFirstFlash];
}
if (nFlash == nLastFlash)
{
nLastFlash = edi;
}
}
}
void AddGlow(short nSector, int nVal)
{
if (nGlowCount >= kMaxGlows) {
return;
}
sGlow[nGlowCount].field_6 = nVal;
sGlow[nGlowCount].nSector = nSector;
sGlow[nGlowCount].field_0 = -1;
sGlow[nGlowCount].field_2 = 0;
nGlowCount++;
}
// ok
void AddFlicker(short nSector, int nVal)
{
if (nFlickerCount >= kMaxFlickers) {
return;
}
sFlicker[nFlickerCount].field_0 = nVal;
sFlicker[nFlickerCount].nSector = nSector;
if (nVal >= 25) {
nVal = 24;
}
sFlicker[nFlickerCount].field_4 = flickermask[nVal];
nFlickerCount++;
}
void DoGlows()
{
bDoGlows++;
if (bDoGlows < 3) {
return;
}
bDoGlows = 0;
for (int i = 0; i < nGlowCount; i++)
{
sGlow[i].field_2++;
short nSector = sGlow[i].nSector;
short nShade = sGlow[i].field_0;
if (sGlow[i].field_2 >= sGlow[i].field_6)
{
sGlow[i].field_2 = 0;
sGlow[i].field_0 = -sGlow[i].field_0;
}
sector[nSector].ceilingshade += nShade;
sector[nSector].floorshade += nShade;
int startwall = sector[nSector].wallptr;
int endwall = startwall + sector[nSector].wallnum - 1;
for (int nWall = startwall; nWall <= endwall; nWall++)
{
wall[nWall].shade += nShade;
// CHECKME - ASM has edx decreasing here. why?
}
}
}
void DoFlickers()
{
bDoFlicks ^= 1;
if (!bDoFlicks) {
return;
}
for (int i = 0; i < nFlickerCount; i++)
{
short nSector = sFlicker[i].nSector;
unsigned int eax = (sFlicker[i].field_4 & 1);
unsigned int edx = (sFlicker[i].field_4 & 1) << 31;
unsigned int ebp = sFlicker[i].field_4 >> 1;
ebp |= edx;
edx = ebp & 1;
sFlicker[i].field_4 = ebp;
if (edx ^ eax)
{
short shade;
if (eax)
{
shade = sFlicker[i].field_0;
}
else
{
shade = -sFlicker[i].field_0;
}
sector[nSector].ceilingshade += shade;
sector[nSector].floorshade += shade;
int startwall = sector[nSector].wallptr;
int endwall = startwall + sector[nSector].wallnum - 1;
for (int nWall = endwall; nWall >= startwall; nWall--)
{
wall[nWall].shade += shade;
// CHECKME - ASM has edx decreasing here. why?
}
}
}
}
// nWall can also be passed in here via nSprite parameter - TODO - rename nSprite parameter :)
void AddFlow(int nSprite, int a, int b)
{
if (nFlowCount >= kMaxFlows)
return;
short nFlow = nFlowCount;
nFlowCount++;
short var_18;
if (b < 2)
{
var_18 = sprite[nSprite].sectnum;
short nPic = sector[var_18].floorpicnum;
short nAngle = sprite[nSprite].ang;
sFlowInfo[nFlow].field_14 = (tilesizx[nPic] << 14) - 1;
sFlowInfo[nFlow].field_18 = (tilesizy[nPic] << 14) - 1;
sFlowInfo[nFlow].field_C = (-Sin(nAngle + 512)) * a;
sFlowInfo[nFlow].field_10 = (-Sin(nAngle)) * a;
}
else
{
short nAngle;
if (b == 2) {
nAngle = 512;
}
else {
nAngle = 1536;
}
var_18 = nSprite;
short nPic = wall[var_18].picnum;
sFlowInfo[nFlow].field_14 = (tilesizx[nPic] * wall[var_18].xrepeat) << 8;
sFlowInfo[nFlow].field_18 = (tilesizy[nPic] * wall[var_18].yrepeat) << 8;
sFlowInfo[nFlow].field_C = (-Sin(nAngle + 512)) * a;
sFlowInfo[nFlow].field_10 = (-Sin(nAngle)) * a;
}
sFlowInfo[nFlow].field_8 = 0;
sFlowInfo[nFlow].field_4 = 0;
sFlowInfo[nFlow].field_0 = var_18;
sFlowInfo[nFlow].field_2 = b;
}
void DoFlows()
{
for (int i = 0; i < nFlowCount; i++)
{
sFlowInfo[i].field_4 += sFlowInfo[i].field_C;
sFlowInfo[i].field_8 += sFlowInfo[i].field_10;
switch (sFlowInfo[i].field_2)
{
case 0:
{
sFlowInfo[i].field_4 &= sFlowInfo[i].field_14;
sFlowInfo[i].field_8 &= sFlowInfo[i].field_18;
short nSector = sFlowInfo[i].field_0;
sector[nSector].floorxpanning = sFlowInfo[i].field_4 >> 14;
sector[nSector].floorypanning = sFlowInfo[i].field_8 >> 14;
break;
}
case 1:
{
short nSector = sFlowInfo[i].field_0;
sector[nSector].ceilingxpanning = sFlowInfo[i].field_4 >> 14;
sector[nSector].ceilingypanning = sFlowInfo[i].field_8 >> 14;
sFlowInfo[i].field_4 &= sFlowInfo[i].field_14;
sFlowInfo[i].field_8 &= sFlowInfo[i].field_18;
break;
}
case 2:
{
short nWall = sFlowInfo[i].field_0;
wall[nWall].xpanning = sFlowInfo[i].field_4 >> 14;
wall[nWall].ypanning = sFlowInfo[i].field_8 >> 14;
if (sFlowInfo[i].field_4 < 0)
{
sFlowInfo[i].field_4 += sFlowInfo[i].field_14;
}
if (sFlowInfo[i].field_8 < 0)
{
sFlowInfo[i].field_8 += sFlowInfo[i].field_18;
}
break;
}
case 3:
{
short nWall = sFlowInfo[i].field_0;
wall[nWall].xpanning = sFlowInfo[i].field_4 >> 14;
wall[nWall].ypanning = sFlowInfo[i].field_8 >> 14;
if (sFlowInfo[i].field_4 >= sFlowInfo[i].field_14)
{
sFlowInfo[i].field_4 -= sFlowInfo[i].field_14;
}
if (sFlowInfo[i].field_8 >= sFlowInfo[i].field_18)
{
sFlowInfo[i].field_8 -= sFlowInfo[i].field_18;
}
break;
}
}
}
}
void DoLights()
{
DoFlickers();
DoGlows();
DoFlows();
}
void SetTorch(int nPlayer, int bTorchOnOff)
{
char buf[40];
if (bTorchOnOff == bTorch) {
return;
}
if (nPlayer != nLocalPlayer) {
return;
}
char *pTempPal = origpalookup[kPalTorch];
palookup[kPalTorch] = palookup[kPalNoTorch];
palookup[kPalNoTorch] = pTempPal;
pTempPal = origpalookup[kPalTorch];
origpalookup[kPalTorch] = origpalookup[kPalNoTorch];
origpalookup[kPalNoTorch] = pTempPal;
pTempPal = origpalookup[kPalTorch2];
origpalookup[kPalTorch2] = origpalookup[kPalNoTorch2];
origpalookup[kPalNoTorch2] = pTempPal;
pTempPal = palookup[kPalTorch2];
palookup[kPalNoTorch2] = palookup[kPalTorch2];
palookup[kPalTorch2] = pTempPal;
if (bTorchOnOff == 2) {
bTorch = bTorch == 0;
}
else {
bTorch = bTorchOnOff;
}
if (bTorch) {
PlayLocalSound(kSoundTorchOn, 0);
}
strcpy(buf, "TORCH IS ");
if (bTorch) {
strcat(buf, "LIT");
}
else {
strcat(buf, "OUT");
}
StatusMessage(150, buf);
}
void BuildFlash(short nPlayer, short nSector, int nVal)
{
if (nPlayer == nLocalPlayer)
{
flash = nVal;
flash = -nVal; // ???
}
}

View file

@ -0,0 +1,17 @@
#ifndef __lighting_h__
#define __lighting_h__
extern short nFlashDepth;
void InitLights();
void AddFlash(short nSector, int x, int y, int z, int val);
void SetTorch(int nPlayer, int bTorchOnOff);
void UndoFlashes();
void DoLights();
void AddFlow(int nSprite, int a, int b);
void BuildFlash(short nPlayer, short nSector, int nVal);
void AddGlow(short nSector, int nVal);
void AddFlicker(short nSector, int nVal);
#endif

562
source/exhumed/src/lion.cpp Normal file
View file

@ -0,0 +1,562 @@
#include "lion.h"
#include "engine.h"
#include "runlist.h"
#include "exhumed.h"
#include "sequence.h"
#include "move.h"
#include "sound.h"
#include "random.h"
#include "trigdat.h"
#include "items.h"
#include <assert.h>
#define kMaxLions 40
short LionCount = -1;
short MoveHook[kMaxLions];
static actionSeq ActionSeq[] = {{54, 1}, {18, 1}, {0, 0}, {10, 0}, {44, 0}, {18, 0}, {26, 0}, {34, 0}, {8, 1}, {9, 1}, {52, 1}, {53, 1}};
struct Lion
{
short nHealth;
short _b;
short nAction;
short nSprite;
short nTarget;
short _f;
short _g;
short _h;
};
Lion LionList[kMaxLions];
void InitLion()
{
LionCount = kMaxLions;
}
int BuildLion(short nSprite, int x, int y, int z, short nSector, short nAngle)
{
LionCount--;
short nLion = LionCount;
if (LionCount < 0) {
return -1;
}
if (nSprite == -1)
{
nSprite = insertsprite(nSector, 104);
}
else
{
changespritestat(nSprite, 104);
x = sprite[nSprite].x;
y = sprite[nSprite].y;
z = sector[sprite[nSprite].sectnum].floorz;
nAngle = sprite[nSprite].ang;
}
assert(nSprite >= 0 && nSprite < kMaxSprites);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
sprite[nSprite].cstat = 0x101;
sprite[nSprite].clipdist = 60;
sprite[nSprite].shade = -12;
sprite[nSprite].xrepeat = 40;
sprite[nSprite].yrepeat = 40;
sprite[nSprite].picnum = 1;
sprite[nSprite].pal = sector[sprite[nSprite].sectnum].ceilingpal;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].ang = nAngle;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].hitag = 0;
sprite[nSprite].extra = -1;
// GrabTimeSlot(3);
LionList[nLion].nAction = 0;
LionList[nLion].nHealth = 500;
LionList[nLion]._b = 0;
LionList[nLion].nSprite = nSprite;
LionList[nLion].nTarget = -1;
LionList[nLion]._g = 0;
LionList[nLion]._f = nLion;
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nLion | 0x130000);
MoveHook[nLion] = runlist_AddRunRec(NewRun, nLion | 0x130000);
nCreaturesLeft++;
return nLion | 0x130000;
}
void FuncLion(int a, int nDamage, int nRun)
{
int var_18 = 0;
short nLion = RunData[nRun].nVal;
assert(nLion >= 0 && nLion < kMaxLions);
short nSprite = LionList[nLion].nSprite;
short nAction = LionList[nLion].nAction;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
default:
{
DebugOut("unknown msg %d for Lion\n", nMessage);
return;
}
case 0x90000:
{
seq_PlotSequence(a, SeqOffsets[kSeqLion] + ActionSeq[nAction].a, LionList[nLion]._b, ActionSeq[nAction].b);
return;
}
case 0xA0000:
{
nDamage = runlist_CheckRadialDamage(nSprite);
// now fall through to 0x80000
}
case 0x80000:
{
if (nDamage && LionList[nLion].nHealth > 0)
{
LionList[nLion].nHealth -= nDamage;
if (LionList[nLion].nHealth <= 0)
{
// R.I.P.
sprite[nSprite].zvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
LionList[nLion].nHealth = 0;
sprite[nSprite].cstat &= 0xFEFE;
nCreaturesLeft--;
if (nAction < 10)
{
DropMagic(nSprite);
if (nMessage == 0xA0000) {
LionList[nLion].nAction = 11;
}
else
{
LionList[nLion].nAction = 10;
}
LionList[nLion]._b = 0;
return;
}
}
else
{
if (a >= 0)
{
short nTarget = a & 0xFFFF;
if (sprite[nTarget].statnum < 199) {
LionList[nLion].nTarget = nTarget;
}
if (nAction != 6)
{
if (RandomSize(8) <= (LionList[nLion].nHealth >> 2))
{
LionList[nLion].nAction = 4;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
}
else if (RandomSize(1))
{
PlotCourseToSprite(nSprite, nTarget);
LionList[nLion].nAction = 5;
LionList[nLion]._g = RandomSize(3);
sprite[nSprite].ang = (sprite[nSprite].ang - (RandomSize(1) << 8)) + (RandomSize(1) << 8);
}
LionList[nLion]._b = 0;
return;
}
}
return;
}
}
return;
}
case 0x20000:
{
if (nAction != 7) {
Gravity(nSprite);
}
short nSeq = SeqOffsets[kSeqLion] + ActionSeq[nAction].a;
sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, LionList[nLion]._b);
seq_MoveSequence(nSprite, nSeq, LionList[nLion]._b);
LionList[nLion]._b++;
if (LionList[nLion]._b >= SeqSize[nSeq])
{
LionList[nLion]._b = 0;
var_18 = 1;
}
short nFlag = FrameFlag[SeqBase[nSeq] + LionList[nLion]._b];
short nTarget = LionList[nLion].nTarget;
int nVal = MoveCreatureWithCaution(nSprite);
switch (nAction)
{
default:
return;
case 0:
case 1:
{
if ((LionList[nLion]._f & 31) == (totalmoves & 31))
{
if (nTarget < 0)
{
nTarget = FindPlayer(nSprite, 40);
if (nTarget >= 0)
{
D3PlayFX(StaticSound[kSound24], nSprite);
LionList[nLion].nAction = 2;
LionList[nLion]._b = 0;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 1;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 1;
LionList[nLion].nTarget = nTarget;
return;
}
}
}
if (nAction)
{
LionList[nLion]._g--;
if (LionList[nLion]._g <= 0)
{
if (RandomBit())
{
sprite[nSprite].ang = RandomWord() & kAngleMask;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 1;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 1;
}
else
{
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
}
LionList[nLion]._g = 100;
}
}
return;
}
case 2:
{
if ((totalmoves & 0x1F) == (LionList[nLion]._f & 0x1F))
{
PlotCourseToSprite(nSprite, nTarget);
short nAng = sprite[nSprite].ang & 0xFFF8;
if (sprite[nSprite].cstat & 0x8000)
{
sprite[nSprite].xvel = Sin(nAng + 512) * 2;
sprite[nSprite].yvel = Sin(nAng) * 2;
}
else
{
sprite[nSprite].xvel = Sin(nAng + 512) >> 1;
sprite[nSprite].yvel = Sin(nAng) >> 1;
}
}
if ((nVal & 0xC000) < 0x8000)
{
break;
}
else if ((nVal & 0xC000) == 0x8000)
{
// loc_378FA:
sprite[nSprite].ang = (sprite[nSprite].ang + 256) & kAngleMask;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 1;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 1;
break;
}
else if ((nVal & 0xC000) == 0xC000)
{
if ((nVal & 0x3FFF) == nTarget)
{
if (sprite[nSprite].cstat == 0x8000)
{
int nAng = getangle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y);
if (AngleDiff(sprite[nSprite].ang, nAng) < 64)
{
LionList[nLion].nAction = 3;
}
}
else
{
LionList[nLion].nAction = 9;
sprite[nSprite].cstat &= 0x7FFF;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
}
LionList[nLion]._b = 0;
break;
}
else
{
// loc_378FA:
sprite[nSprite].ang = (sprite[nSprite].ang + 256) & kAngleMask;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 1;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 1;
break;
}
}
break;
}
case 3:
{
if (nTarget == -1)
{
LionList[nLion].nAction = 1;
LionList[nLion]._g = 50;
}
else
{
if (PlotCourseToSprite(nSprite, nTarget) >= 768)
{
LionList[nLion].nAction = 2;
}
else if (nFlag & 0x80)
{
runlist_DamageEnemy(nTarget, nSprite, 10);
}
}
break;
}
case 4:
{
if (var_18)
{
LionList[nLion].nAction = 2;
LionList[nLion]._b = 0;
}
if (nVal & 0x20000)
{
sprite[nSprite].xvel >>= 1;
sprite[nSprite].yvel >>= 1;
}
return;
}
case 5:
{
LionList[nLion]._g--;
if (LionList[nLion]._g <= 0)
{
sprite[nSprite].zvel = -4000;
LionList[nLion]._g = 0;
int x = sprite[nSprite].x;
int y = sprite[nSprite].y;
int z = sprite[nSprite].z - (GetSpriteHeight(nSprite) >> 1);
int var_40 = 0x7FFFFFFF;
short nSector = sprite[nSprite].sectnum;
short var_28 = sprite[nSprite].ang;
short nAng = (sprite[nSprite].ang - 512) & kAngleMask;
for (int i = 0; i < 5; i++)
{
short hitsect, hitwall, hitsprite;
int hitx, hity, hitz;
hitscan(x, y, z, nSector, Sin(nAng + 512), Sin(nAng), 0, &hitsect, &hitwall, &hitsprite, &hitx, &hity, &hitz, CLIPMASK1);
if (hitwall > -1)
{
int ebx = klabs(hitx - x);
int eax = klabs(hity - y);
ebx += eax;
if (ebx < var_40)
{
var_40 = ebx;
var_28 = nAng;
}
}
nAng += 256;
nAng &= kAngleMask;
}
sprite[nSprite].ang = var_28;
LionList[nLion].nAction = 6;
sprite[nSprite].xvel = (Sin(sprite[nSprite].ang + 512)) - (Sin(sprite[nSprite].ang + 512) >> 3);
sprite[nSprite].yvel = (Sin(sprite[nSprite].ang)) - (Sin(sprite[nSprite].ang) >> 3);
D3PlayFX(StaticSound[kSound24], nSprite);
}
return;
}
case 6:
{
if (nVal & 0x30000)
{
LionList[nLion].nAction = 2;
LionList[nLion]._b = 0;
return;
}
if ((nVal & 0xC000) == 0x8000)
{
LionList[nLion].nAction = 7;
sprite[nSprite].ang = (GetWallNormal(nVal & 0x3FFF) + 1024) & kAngleMask;
LionList[nLion]._g = RandomSize(4);
return;
}
else if ((nVal & 0xC000) == 0xC000)
{
if ((nVal & 0x3FFF) == nTarget)
{
int nAng = getangle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y);
if (AngleDiff(sprite[nSprite].ang, nAng) < 64)
{
LionList[nLion].nAction = 3;
LionList[nLion]._b = 0;
}
}
else
{
// loc_378FA:
sprite[nSprite].ang = (sprite[nSprite].ang + 256) & kAngleMask;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 1;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 1;
}
}
return;
}
case 7:
{
LionList[nLion]._g--;
if (LionList[nLion]._g <= 0)
{
LionList[nLion]._g = 0;
if (nTarget > -1)
{
PlotCourseToSprite(nSprite, nTarget);
}
else
{
sprite[nSprite].ang = (RandomSize(9) + (sprite[nSprite].ang + 768)) & kAngleMask;
}
sprite[nSprite].zvel = -1000;
LionList[nLion].nAction = 6;
sprite[nSprite].xvel = (Sin(sprite[nSprite].ang + 512)) - (Sin(sprite[nSprite].ang + 512) >> 3);
sprite[nSprite].yvel = (Sin(sprite[nSprite].ang)) - (Sin(sprite[nSprite].ang) >> 3);
D3PlayFX(StaticSound[kSound24], nSprite);
}
return;
}
case 8:
{
if (var_18)
{
LionList[nLion].nAction = 2;
LionList[nLion]._b = 0;
sprite[nSprite].cstat |= 0x8000;
}
return;
}
case 9:
{
if (var_18)
{
LionList[nLion]._b = 0;
LionList[nLion].nAction = 2;
sprite[nSprite].cstat |= 0x101;
}
return;
}
case 10:
case 11:
{
if (var_18)
{
runlist_SubRunRec(sprite[nSprite].owner);
runlist_SubRunRec(MoveHook[nLion]);
sprite[nSprite].cstat = 0x8000;
}
return;
}
}
// loc_379AD: ?
if (nAction != 1 && nTarget != -1)
{
if (!(sprite[nTarget].cstat & 0x101))
{
LionList[nLion].nAction = 1;
LionList[nLion]._b = 0;
LionList[nLion]._g = 100;
LionList[nLion].nTarget = -1;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
}
}
return;
}
}
}

View file

@ -0,0 +1,9 @@
#ifndef __lion_h__
#define __lion_h__
void InitLion();
int BuildLion(short nSprite, int x, int y, int z, short nSector, short nAngle);
void FuncLion(int, int, int);
#endif

View file

@ -0,0 +1,29 @@
#include "exhumed.h"
extern "C" {
#ifndef __WATCOMC__
#include "build.h"
#include "osd.h"
#include "baselayer.h"
#endif
void faketimerhandler(void)
{
}
#ifdef __WATCOMC__
void main(int argc, char *argv[])
{
ExhumedMain(argc, argv); // main function in exhumed.cpp
}
#else
int app_main(int argc, char *argv[])
{
wm_setapptitle("Exhumed/PowerSlave PC RE");
ExhumedMain(argc, argv); // main function in exhumed.cpp
return 0;
}
#endif
}

279
source/exhumed/src/map.cpp Normal file
View file

@ -0,0 +1,279 @@
#include "typedefs.h"
#include <string.h>
#include "player.h"
#include "init.h"
#include "engine.h"
#include "exhumed.h"
short bShowTowers = kTrue; //kFalse; REVERT to kFalse
long ldMapZoom;
long lMapZoom;
void MarkSectorSeen(short nSector);
void InitMap()
{
memset(show2dsector, 0, sizeof(show2dsector));
memset(show2dwall, 0, sizeof(show2dwall));
memset(show2dsprite, 0, sizeof(show2dsprite));
ldMapZoom = 64;
lMapZoom = 1000;
}
void GrabMap()
{
for (int i = 0; i < numsectors; i++) {
MarkSectorSeen(i);
}
}
void MarkSectorSeen(short nSector)
{
if (!((1 << (nSector & 7)) & show2dsector[nSector >> 3]))
{
show2dsector[nSector >> 3] |= 1 << (nSector & 7);
short startwall = sector[nSector].wallptr;
short nWalls = sector[nSector].wallnum;
short endwall = startwall + nWalls;
while (startwall <= endwall)
{
show2dwall[startwall >> 3] = (1 << (startwall & 7)) | show2dwall[startwall >> 3];
startwall++;
}
}
}
void drawoverheadmap(long cposx, long cposy, long czoom, short cang)
{
#ifndef __WATCOMC__ // FIXME - Won't compile on Watcom
long xvect = sintable[(2048 - cang) & 2047] * czoom;
long yvect = sintable[(1536 - cang) & 2047] * czoom;
long xvect2 = mulscale(xvect, yxaspect, 16);
long yvect2 = mulscale(yvect, yxaspect, 16);
// draw player position arrow
drawline256(xdim << 11, (ydim << 11) - 20480, xdim << 11, (ydim << 11) + 20480, 24);
drawline256((xdim << 11) - 20480, ydim << 11, xdim << 11, (ydim << 11) - 20480, 24);
drawline256((xdim << 11) + 20480, ydim << 11, xdim << 11, (ydim << 11) - 20480, 24);
short nPlayerSprite = PlayerList[nLocalPlayer].nSprite;
int nPlayerZ = sprite[nPlayerSprite].z;
for (int nSector = 0; nSector < numsectors; nSector++)
{
short startwall = sector[nSector].wallptr;
short nWalls = sector[nSector].wallnum;
short endwall = startwall + nWalls - 1;
int nCeilZ = sector[nSector].ceilingz;
int nFloorZ = sector[nSector].floorz;
int nZVal = nFloorZ - nPlayerZ;
if (nZVal < 0) {
nZVal = -nZVal;
}
int var_10 = nZVal >> 13;
if (var_10 > 12) {
var_10 = 12;
}
var_10 = 111 - var_10;
int startwallB = startwall;
for (int nWall = startwall; nWall <= endwall; nWall++)
{
short nextwall = wall[nWall].nextwall;
if (nextwall >= 0)
{
if (show2dwall[nWall >> 3] & (1 << (nWall & 7)))
{
if (nextwall <= nWall || (show2dwall[nextwall >> 3] & (1 << (nextwall & 7))) <= 0)
{
if (nCeilZ != sector[wall[nWall].nextsector].ceilingz ||
nFloorZ != sector[wall[nWall].nextsector].floorz ||
((wall[nextwall].cstat | wall[nWall].cstat) & 0x30))
{
long ox = wall[nWall].x - cposx;
long oy = wall[nWall].y - cposy;
long x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
long y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
int nWall2 = wall[nWall].point2;
ox = wall[nWall2].x - cposx;
oy = wall[nWall2].y - cposy;
long x2 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
long y2 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
drawline256(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), var_10);
/*
drawline256(
((unsigned __int64)(v4 * (signed __int64)v12) >> 16)
- ((unsigned __int64)(v5 * (signed __int64)v13) >> 16)
+ (xdim << 11),
((unsigned __int64)(v42 * (signed __int64)v12) >> 16)
+ ((unsigned __int64)(v43 * (signed __int64)v13) >> 16)
+ (ydim << 11),
(build_xdim << 11)
+ ((unsigned __int64)(v4 * (signed __int64)(*v14 - v31)) >> 16)
- ((unsigned __int64)(v5 * (signed __int64)(v14[1] - v30)) >> 16),
ydim << 11)
+ ((unsigned __int64)(v43 * (signed __int64)(v14[1] - v30)) >> 16)
+ ((unsigned __int64)(v42 * (signed __int64)(*v14 - v31)) >> 16),
v48);
*/
}
}
}
}
}
}
// int var_4C = 0;
// int var_48 = 0;
for (int nSector = 0; nSector < numsectors; nSector++)
{
int startwall = sector[nSector].wallptr;
int nWalls = sector[nSector].wallnum;
int endwall = startwall + nWalls - 1;
int nFloorZ = sector[nSector].floorz;
int nVal = nFloorZ - nPlayerZ;
if (nVal < 0) {
nVal = -nVal;
}
int var_14 = nVal >> 13;
if (var_14 <= 15)
{
var_14 = 111 - var_14;
for (int nWall = startwall; nWall <= endwall; nWall++)
{
if (wall[nWall].nextwall < 0)
{
if (show2dwall[nWall >> 3] & (1 << (nWall & 7)))
{
if (tilesizx[wall[nWall].picnum] && tilesizy[wall[nWall].picnum])
{
long ox = wall[nWall].x - cposx;
long oy = wall[nWall].y - cposy;
long x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
long y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
int nWall2 = wall[nWall].point2;
ox = wall[nWall2].x - cposx;
oy = wall[nWall2].y - cposy;
long x2 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
long y2 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
drawline256(x1 + (xdim << 11), y1 + (ydim << 11), x2 + (xdim << 11), y2 + (ydim << 11), 24);
/*
v19 = *v17 - v31;
v20 = v17[1] - v30;
v21 = &wall[8 * *((_WORD *)v17 + 4)];
build_drawline256(
(build_xdim << 11)
+ ((unsigned __int64)(v4 * (signed __int64)v19) >> 16)
- ((unsigned __int64)(v5 * (signed __int64)v20) >> 16),
(build_ydim << 11)
+ ((unsigned __int64)(v42 * (signed __int64)v19) >> 16)
+ ((unsigned __int64)(v43 * (signed __int64)v20) >> 16),
(build_xdim << 11)
+ ((unsigned __int64)(v4 * (signed __int64)(*v21 - v31)) >> 16)
- ((unsigned __int64)(v5 * (signed __int64)(v21[1] - v30)) >> 16),
(build_ydim << 11)
+ ((unsigned __int64)(v42 * (signed __int64)(*v21 - v31)) >> 16)
+ ((unsigned __int64)(v43 * (signed __int64)(v21[1] - v30)) >> 16),
v46);
*/
}
}
}
}
if (bShowTowers)
{
for (int nSprite = headspritestat[406]; nSprite != -1; nSprite = nextspritestat[nSprite])
{
long ox = sprite[nSprite].x - cposx; // var_64
long oy = sprite[nSprite].y - cposx; // var_68
// int var_58 = mulscale(var_64, xvect, 16) - mulscale(var_68, yvect, 16);
long x1 = mulscale(ox, xvect, 16) - mulscale(oy, yvect, 16);
long y1 = mulscale(oy, xvect2, 16) + mulscale(ox, yvect2, 16);
//int var_58 = mulscale(var_64, xvect, 16) - mulscale(var_68, yvect, 16);
//int esi = mulscale(var_68, xvect2, 16) + mulscale(var_65, yvect2, 16)
//v25 = ((unsigned __int64)(v4 * (signed __int64)ox) >> 16)
// - ((unsigned __int64)(v5 * (signed __int64)oy) >> 16);
//v26 = ((unsigned __int64)(v42 * (signed __int64)ox) >> 16)
// + ((unsigned __int64)(v43 * (signed __int64)oy) >> 16);
//v27 = v26 + 2048;
//v28 = v26 + 2048 + (ydim << 11);
//v26 -= 2048;
// v25 is x1
// v26 is y1
// v27 is y1 + 2048
// v28 is y1 + 2048 + (ydim << 1);
drawline256(
x1 - 2048 + (xdim << 11),
y1 - 2048 + (ydim << 11),
x1 - 2048 + (xdim << 11),
y1 + 2048 + (ydim << 1),
170);
drawline256(
x1 + (xdim << 11),
y1 + (ydim << 11),
x1 + (xdim << 11),
y1 + 2048 + (ydim << 11),
170);
drawline256(
x1 + 2048 + (xdim << 11),
y1 + (ydim << 11),
x1 + 2048 + (xdim << 11),
y1 + 2048 + (ydim << 11),
170);
}
}
}
}
#endif
}
void UpdateMap()
{
if (sector[initsect].ceilingpal != 3 || (nPlayerTorch[nLocalPlayer] != 0)) {
MarkSectorSeen(initsect);
}
}
void DrawMap()
{
if (!nFreeze) {
drawoverheadmap(initx, inity, lMapZoom, inita);
}
}

16
source/exhumed/src/map.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef __map_h__
#define __map_h__
#include "typedefs.h"
extern short bShowTowers;
extern long ldMapZoom;
extern long lMapZoom;
void InitMap();
void GrabMap();
void UpdateMap();
void DrawMap();
#endif

2356
source/exhumed/src/menu.cpp Normal file

File diff suppressed because it is too large Load diff

60
source/exhumed/src/menu.h Normal file
View file

@ -0,0 +1,60 @@
#ifndef __menu_h__
#define __menu_h__
#include "player.h"
#include "typedefs.h"
#include <stdio.h>
#pragma pack(1)
// should be 75 bytes
struct GameStat
{
uchar nMap;
short nWeapons;
short nCurrentWeapon;
short clip;
short items;
Player player;
short nLives;
};
#pragma pack()
extern GameStat GameStats;
extern unsigned char cinemapal[];
extern short SavePosition;
int showmap(short nLevel, short nLevelNew, short nLevelBest);
void ClearCinemaSeen();
void menu_DoPlasma();
int menu_Menu(int val);
void menu_AdjustVolume();
short menu_GameLoad(int nSlot);
void menu_GameLoad2(FILE *fp);
void menu_GameSave2(FILE *fp);
void menu_GameSave(int nSaveSlot);
int menu_DrawTheMap(int nLevel, int param_B, int param_C);
void DoEnergyTile();
int LoadCinemaPalette(int nPal);
void CinemaFadeIn();
void ReadyCinemaText(ushort nVal);
BOOL AdvanceCinemaText();
void DoFailedFinalScene();
void DoLastLevelCinema();
void DoAfterCinemaScene(int nLevel);
void InitEnergyTile();
#endif

View file

@ -0,0 +1,53 @@
/*
Name: MonoClear_
address = 0001:0001CF5A
module index = 24
kind: (code)
Name: MonoInUse_
address = 0001:0001CF8A
module index = 24
kind: (code)
Name: MonoOpen_
address = 0001:0001CF8A
module index = 24
kind: (code)
Name: MonoClose_
address = 0001:0001CF8D
module index = 24
kind: (code)
Name: MonoOut_
address = 0001:0001CFAA
module index = 24
kind: (code)
Name: CACopy_
address = 0001:0001D1C0
module index = 24
kind: (static pubdef) (code)
Name: CAFill_
address = 0001:0001D1CD
module index = 24
kind: (static pubdef) (code)
Name: MonoQuery_
address = 0001:0001D1E6
module index = 24
kind: (code)
Name: _rowCur
address = 0003:000073D8
module index = 24
kind: (data)
Name: _colCur
address = 0003:000073DC
module index = 24
kind: (data)
Name: _fMonoOpen
address = 0003:000073E0
module index = 24
kind: (data)
*/
#include "mono.h"
int rowCur = 0;
int colCur = 0;

View file

@ -0,0 +1,7 @@
#ifndef __mono_h__
#define __mono_h__
#endif

1519
source/exhumed/src/move.cpp Normal file

File diff suppressed because it is too large Load diff

60
source/exhumed/src/move.h Normal file
View file

@ -0,0 +1,60 @@
#ifndef __move_h__
#define __move_h__
// 16 bytes
struct BlockInfo
{
int x;
int y;
int field_8;
short nSprite;
};
extern BlockInfo sBlockInfo[];
extern long hihit;
extern short nChunkSprite[];
signed int lsqrt(int a1);
void MoveThings();
void ResetMoveFifo();
void InitChunks();
void InitPushBlocks();
void Gravity(short nSprite);
short UpdateEnemy(short *nEnemy);
int MoveCreature(short nSprite);
int MoveCreatureWithCaution(int nSprite);
void WheresMyMouth(int nPlayer, int *x, int *y, int *z, short *sectnum);
int GetSpriteHeight(int nSprite);
int GrabBody();
int GrabBodyGunSprite();
void CreatePushBlock(int nSector);
void FuncCreatureChunk(int a, int, int nRun);
int FindPlayer(int nSprite, int nVal);
int BuildCreatureChunk(int nVal, int nPic);
void BuildNear(int x, int y, int walldist, int nSector);
int BelowNear(short nSprite);
int PlotCourseToSprite(int nSprite1, int nSprite2);
void CheckSectorFloor(short nSector, int z, long *a, long *b);
int GetAngleToSprite(int nSprite1, int nSprite2);
int GetWallNormal(short nWall);
int GetUpAngle(short nSprite1, int nVal, short nSprite2, int ecx);
void MoveSector(short nSector, int nAngle, int *nXVel, int *nYVel);
int AngleChase(int nSprite, int nSprite2, int ebx, int ecx, int push1);
void SetQuake(short nSprite, int nVal);
#endif

View file

@ -0,0 +1,210 @@
#include "engine.h"
#include "exhumed.h"
#include "names.h"
#include "movie.h"
#include "cdrom.h"
#include "light.h"
#include <cstdio>
#include <cstring>
#include "baselayer.h"
#include "typedefs.h"
#include "keyboard.h"
enum {
kFramePalette = 0,
kFrameSound,
kFrameImage,
kFrameDone
};
uchar lh[32] = { 0 };
char streambuf[2205];
char byte_1C6DF5[2205];
static BYTE* CurFrame = NULL;
int serve_sample()
{
// if (!SoundCardActive()) {
// return 1;
// }
return 0;
}
int ReadFrame(FILE *fp)
{
static int nFrame = 0;
DebugOut("Reading frame %d...\n", nFrame);
nFrame++;
uchar nType;
uchar var_1C;
int nSize;
ushort yOffset;
uchar xOffset;
uchar nPixels;
uchar palette[768];
while (1)
{
if (fread(&nType, 1, sizeof(nType), fp) == 0) {
return 0;
}
fread(&nSize, sizeof(nSize), 1, fp);
nType--;
if (nType > 3) {
continue;
}
switch (nType)
{
case kFramePalette:
{
fread(palette, sizeof(palette[0]), sizeof(palette) / sizeof(palette[0]), fp);
fread(&var_1C, sizeof(var_1C), 1, fp);
MySetPalette(palette);
memset(CurFrame, overscanindex, 4); //sizeof(CurFrame));
continue;
}
case kFrameSound:
{
DebugOut("Reading sound block size %d...\n", nSize);
// TODO - just skip for now
fseek(fp, nSize, SEEK_CUR);
continue;
}
case kFrameImage:
{
DebugOut("Reading image block size %d...\n", nSize);
if (nSize == 0) {
continue;
}
BYTE *pFrame = CurFrame;
int nRead = fread(&yOffset, 1, sizeof(yOffset), fp);
nSize -= nRead;
pFrame += yOffset * 200; // row position
while (nSize > 0)
{
fread(&xOffset, sizeof(xOffset), 1, fp);
fread(&nPixels, sizeof(nPixels), 1, fp);
nSize -= 2;
pFrame += xOffset;
if (nPixels)
{
int nRead = fread(pFrame, 1, nPixels, fp);
pFrame += nRead;
nSize -= nRead;
}
}
break;
}
case kFrameDone:
{
return 1;
break;
}
}
}
}
void PlayMovie(const char *fileName)
{
char buffer[256];
int bDoFade = 1;
if (bNoCDCheck)
{
sprintf(buffer, "C:\\PS\\%s", fileName);
}
else
{
char driveLetter = GetCDDriveLetter();
if (!driveLetter) {
driveLetter = 'C';
}
sprintf(buffer, "%c:%s", driveLetter, fileName);
}
tileLoad(kMovieTile);
CurFrame = (BYTE*)waloff[kMovieTile];
FILE *fp = fopen(buffer, "rb");
if (fp == NULL)
{
DebugOut("Can't open movie file '%s' on CD-ROM\n", buffer);
fp = fopen(fileName, "rb");
if (fp == NULL)
{
DebugOut("Can't open movie file on hard drive\n");
return;
}
}
fread(lh, sizeof(lh), 1, fp);
memset(streambuf, 0, sizeof(streambuf));
memset(byte_1C6DF5, 0, sizeof(byte_1C6DF5));
// sound stuff
// clear keys
KB_FlushKeyboardQueue();
KB_ClearKeysDown();
if (bDoFade) {
StartFadeIn();
}
int angle = 1536;
int z = 0;
if (ReadFrame(fp))
{
while (!KB_KeyWaiting())
{
handleevents();
if (z < 65536) { // Zoom - normal zoom is 65536.
z += 2048;
}
if (angle != 0) {
angle += 16;
if (angle == 2048) {
angle = 0;
}
}
rotatesprite(160 << 16, 100 << 16, z, angle, kMovieTile, 0, 1, 2, 0, 0, nScreenHeight - 1, nScreenWidth - 1);
if (bDoFade) {
bDoFade = DoFadeIn();
}
videoNextPage();
if (ReadFrame(fp) == 0) {
break;
}
}
}
if (KB_KeyWaiting()) {
KB_GetCh();
}
fclose(fp);
}

View file

@ -0,0 +1,7 @@
#ifndef __movie_h__
#define __movie_h__
void PlayMovie(const char *fileName);
#endif

View file

@ -0,0 +1,514 @@
#include "mummy.h"
#include "sequence.h"
#include "move.h"
#include "map.h"
#include "sound.h"
#include "exhumed.h"
#include "random.h"
#include "trigdat.h"
#include "bullet.h"
#include "items.h"
#include <assert.h>
#include "engine.h"
short nMummies = -1;
struct Mummy
{
short nHealth;
short B;
short nAction;
short nSprite;
short nTarget;
short F;
short G;
short H;
};
Mummy MummyList[kMaxMummies];
static actionSeq ActionSeq[] = {
{8, 0},
{0, 0},
{16, 0},
{24, 0},
{32, 1},
{40, 1},
{48, 1},
{50, 0}
};
// done
void InitMummy()
{
nMummies = 0;
}
// done
int BuildMummy(int nSprite, int x, int y, int z, int nSector, int nAngle)
{
if (nMummies >= kMaxMummies) {
return -1;
}
short nMummy = nMummies++;
if (nSprite == -1)
{
nSprite = insertsprite(nSector, 102);
}
else
{
x = sprite[nSprite].x;
y = sprite[nSprite].y;
z = sprite[nSprite].z;
nAngle = sprite[nSprite].ang;
changespritestat(nSprite, 102);
}
assert(nSprite >= 0 && nSprite < kMaxSprites);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
sprite[nSprite].cstat = 0x101;
sprite[nSprite].shade = -12;
sprite[nSprite].clipdist = 32;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].xrepeat = 42;
sprite[nSprite].yrepeat = 42;
sprite[nSprite].pal = sector[sprite[nSprite].sectnum].ceilingpal;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].ang = nAngle;
sprite[nSprite].picnum = 1;
sprite[nSprite].hitag = 0;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].extra = -1;
// GrabTimeSlot(3);
MummyList[nMummy].nAction = 0;
MummyList[nMummy].nHealth = 640;
MummyList[nMummy].B = 0;
MummyList[nMummy].nSprite = nSprite;
MummyList[nMummy].nTarget = -1;
MummyList[nMummy].F = nMummy;
MummyList[nMummy].G = 0;
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nMummy | 0xE0000);
MummyList[nMummy].H = runlist_AddRunRec(NewRun, nMummy | 0xE0000);
nCreaturesLeft++;
return (nMummy | 0xE0000);
}
// done
void CheckMummyRevive(short nMummy)
{
short nSprite = MummyList[nMummy].nSprite;
for (int i = 0; i < nMummies; i++)
{
if (i != nMummy)
{
short nSprite2 = MummyList[i].nSprite;
if (sprite[nSprite2].statnum != 102) {
continue;
}
if (MummyList[i].nAction != 5) {
continue;
}
int x = sprite[nSprite2].x - sprite[nSprite].x;
if (x < 0) {
x = -x;
}
x = x >> 8;
int y = sprite[nSprite2].y - sprite[nSprite].y;
if (y < 0) {
y = -y;
}
y = y >> 8;
if (x <= 20 && y <= 20)
{
int bCanSee = cansee(sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z - 8192, sprite[nSprite].sectnum,
sprite[nSprite2].x, sprite[nSprite2].y, sprite[nSprite2].z - 8192, sprite[nSprite2].sectnum);
if (bCanSee)
{
sprite[nSprite2].cstat = 0;
MummyList[i].nAction = 6;
MummyList[i].B = 0;
}
}
}
}
}
void FuncMummy(int a, int nDamage, int nRun)
{
short nMummy = RunData[nRun].nVal;
assert(nMummy >= 0 && nMummy < kMaxMummies);
short nTarget = UpdateEnemy(&MummyList[nMummy].nTarget);
short nSprite = MummyList[nMummy].nSprite;
short nAction = MummyList[nMummy].nAction;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
case 0x20000:
{
Gravity(nSprite);
int nSeq = SeqOffsets[kSeqMummy] + ActionSeq[nAction].a;
sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, MummyList[nMummy].B);
short nFrame = SeqBase[nSeq] + MummyList[nMummy].B;
short nFrameFlag = FrameFlag[nFrame];
seq_MoveSequence(nSprite, nSeq, MummyList[nMummy].B);
short ecx = 0;
MummyList[nMummy].B++;
if (MummyList[nMummy].B >= SeqSize[nSeq])
{
MummyList[nMummy].B = 0;
ecx = 1;
}
if (nTarget != -1 && nAction < 4)
{
if (!sprite[nTarget].cstat && nAction)
{
MummyList[nMummy].nAction = 0;
MummyList[nMummy].B = 0;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
}
}
int nMov = MoveCreatureWithCaution(nSprite);
if (nAction > 7)
return;
switch (nAction)
{
case 0:
{
if ((MummyList[nMummy].F & 31) == (totalmoves & 31))
{
sprite[nSprite].cstat = 0x101;
if (nTarget < 0)
{
int nPlayerSprite = FindPlayer(nSprite, 100);
if (nPlayerSprite >= 0)
{
D3PlayFX(StaticSound[kSound7], nSprite);
MummyList[nMummy].B = 0;
MummyList[nMummy].nTarget = nPlayerSprite;
MummyList[nMummy].nAction = 1;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 2;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 2;
MummyList[nMummy].G = 90;
}
}
}
return;
}
case 1:
{
if (MummyList[nMummy].G > 0)
{
MummyList[nMummy].G--;
}
if ((MummyList[nMummy].F & 31) == (totalmoves & 31))
{
sprite[nSprite].cstat = 0x101;
PlotCourseToSprite(nSprite, nTarget);
if (MummyList[nMummy].nAction == 1)
{
if (RandomBit())
{
int nTargetHeight = GetSpriteHeight(nTarget);
int nSpriteHeight = GetSpriteHeight(nSprite);
if (cansee(sprite[nSprite].x, sprite[nSprite].y, sprite[nSprite].z - nSpriteHeight, sprite[nSprite].sectnum, sprite[nTarget].x, sprite[nTarget].y, sprite[nTarget].z - nTargetHeight, sprite[nTarget].sectnum))
{
MummyList[nMummy].nAction = 3;
MummyList[nMummy].B = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
return;
}
}
}
if (!MummyList[nMummy].B)
{
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 1;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 1;
}
if (sprite[nSprite].xvel || sprite[nSprite].yvel)
{
if (sprite[nSprite].xvel > 0)
{
sprite[nSprite].xvel -= 1024;
if (sprite[nSprite].xvel < 0) {
sprite[nSprite].xvel = 0;
}
}
else if (sprite[nSprite].xvel < 0)
{
sprite[nSprite].xvel += 1024;
if (sprite[nSprite].xvel > 0) {
sprite[nSprite].xvel = 0;
}
}
if (sprite[nSprite].yvel > 0)
{
sprite[nSprite].yvel -= 1024;
if (sprite[nSprite].yvel < 0) {
sprite[nSprite].yvel = 0;
}
}
else if (sprite[nSprite].yvel < 0)
{
sprite[nSprite].yvel += 1024;
if (sprite[nSprite].yvel > 0) {
sprite[nSprite].yvel = 0;
}
}
}
if (nMov)
{
switch (nMov & 0xC000)
{
case 0x8000:
{
sprite[nSprite].ang = (sprite[nSprite].ang + ((RandomWord() & 0x3FF) + 1024)) & kAngleMask;
sprite[nSprite].xvel = Sin(sprite[nSprite].ang + 512) >> 2;
sprite[nSprite].yvel = Sin(sprite[nSprite].ang) >> 2;
return;
}
case 0xC000:
{
if ((nMov & 0x3FFF) == nTarget)
{
int nAngle = getangle(sprite[nTarget].x - sprite[nSprite].x, sprite[nTarget].y - sprite[nSprite].y);
if (AngleDiff(sprite[nSprite].ang, nAngle) < 64)
{
MummyList[nMummy].nAction = 2;
MummyList[nMummy].B = 0;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
}
}
return;
}
}
}
}
break;
}
case 2:
{
if (nTarget == -1)
{
MummyList[nMummy].nAction = 0;
MummyList[nMummy].B = 0;
}
else
{
if (PlotCourseToSprite(nSprite, nTarget) >= 1024)
{
MummyList[nMummy].nAction = 1;
MummyList[nMummy].B = 0;
}
else if (nFrameFlag & 0x80)
{
runlist_DamageEnemy(nTarget, nSprite, 5);
}
}
return;
}
case 3:
{
if (ecx)
{
MummyList[nMummy].B = 0;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].G = 100;
MummyList[nMummy].nTarget = -1;
return;
}
else if (nFrameFlag & 0x80)
{
SetQuake(nSprite, 100);
// low 16 bits of returned var contains the sprite index, the high 16 the bullet number
int nBullet = BuildBullet(nSprite, 9, 0, 0, 0x0FFFFC400, sprite[nSprite].ang, nTarget + 10000, 1);
CheckMummyRevive(nMummy);
if (nBullet > -1)
{
if (!RandomSize(3))
{
short a = nBullet >> 16;
short b = nBullet & 0xFFFF;
// FIXME CHECKME - nBullet & 0xFFFF can be -1. Original code doesn't handle this??
SetBulletEnemy(nBullet >> 16, nTarget); // isolate the bullet number (shift off the sprite index)
sprite[nBullet & 0xFFFF].pal = 5;
}
}
}
return;
}
case 4:
{
if (ecx)
{
MummyList[nMummy].B = 0;
MummyList[nMummy].nAction = 5;
}
return;
}
case 5:
{
MummyList[nMummy].B = 0;
return;
}
case 6:
{
if (ecx)
{
MummyList[nMummy].nAction = 0;
sprite[nSprite].cstat = 0x101;
MummyList[nMummy].nHealth = 300;
MummyList[nMummy].nTarget = -1;
nCreaturesLeft++;
}
return;
}
case 7:
{
if (nMov & 0x20000)
{
sprite[nSprite].xvel >>= 1;
sprite[nSprite].yvel >>= 1;
}
if (ecx)
{
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
MummyList[nMummy].nAction = 0;
MummyList[nMummy].B = 0;
sprite[nSprite].cstat = 0x101;
MummyList[nMummy].nTarget = -1;
}
return;
}
}
return;
}
case 0x90000:
{
seq_PlotSequence(a & 0xFFFF, SeqOffsets[kSeqMummy] + ActionSeq[nAction].a, MummyList[nMummy].B, ActionSeq[nAction].b);
return;
}
case 0xA0000:
{
if (MummyList[nMummy].nHealth <= 0)
return;
nDamage = runlist_CheckRadialDamage(nSprite);
// fall through to 0x80000
}
case 0x80000:
{
if (nDamage <= 0)
return;
if (MummyList[nMummy].nHealth <= 0) {
return;
}
MummyList[nMummy].nHealth -= nDamage;
if (MummyList[nMummy].nHealth <= 0)
{
MummyList[nMummy].nHealth = 0;
sprite[nSprite].cstat &= 0xFEFE;
nCreaturesLeft--;
DropMagic(nSprite);
MummyList[nMummy].B = 0;
MummyList[nMummy].nAction = 4;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].z = sector[sprite[nSprite].sectnum].floorz;
}
else
{
if (!RandomSize(2))
{
MummyList[nMummy].nAction = 7;
MummyList[nMummy].B = 0;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
}
}
return;
}
default:
{
DebugOut("unknown msg %d for Mummy\n", a & 0x7F0000);
break;
}
}
}

View file

@ -0,0 +1,14 @@
#ifndef __mummy_h__
#define __mummy_h__
#include "runlist.h"
#define kMaxMummies 150
void InitMummy();
int BuildMummy(int val, int x, int y, int z, int nSector, int angle);
void FuncMummy(int nSector, int edx, int nRun);
#endif

6150
source/exhumed/src/names.h Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,41 @@
// this is net.c in the original code
#include "typedefs.h"
#include "network.h"
#include "serial.h"
#include "input.h"
short nNetMoveFrames = 0;
void SendGoodbye()
{
bSendBye = kTrue;
UpdateInputs();
}
void UpdateNetInputs()
{
}
int InitNet(short nSocket, int nPlayers)
{
return 0;
}
int InitSerial()
{
return 1;
}
void AbortNetworkPlay()
{
}
void UnInitNet()
{
}

View file

@ -0,0 +1,14 @@
#ifndef __network_h__
#define __network_h__
extern short nNetMoveFrames;
void SendGoodbye();
void UpdateNetInputs();
int InitNet(short nSocket, int nPlayers);
int InitSerial();
void AbortNetworkPlay();
void UnInitNet();
#endif

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,69 @@
#ifndef __object_h__
#define __object_h__
#define kMaxPoints 1024
#define kMaxSlides 128
#define kMaxElevs 1024
enum kStatus
{
kStatDestructibleSprite = 97,
kStat98,
kStatExplodeTrigger = 141,
kStatExplodeTarget = 152
};
extern short nSmokeSparks;
extern short nDronePitch;
extern long lFinaleStart;
extern short nFinaleSpr;
void InitObjects();
void InitElev();
void InitPoint();
void InitSlide();
void InitWallFace();
void DoDrips();
void DoMovingSects();
void DoFinale();
void PostProcess();
void FuncElev(int, int, int);
void FuncWallFace(int, int, int);
void FuncSlide(int, int, int);
void FuncObject(int, int, int);
void FuncTrap(int, int, int);
void FuncEnergyBlock(int, int, int);
void FuncSpark(int, int, int);
void SnapBobs(short nSectorA, short nSectorB);
short FindWallSprites(short nSector);
void AddMovingSector(int nSector, int edx, int ebx, int ecx);
int BuildWallSprite(int nSector);
void ProcessTrailSprite(int nSprite, int nLotag, int nHitag);
void AddSectorBob(int nSector, int nHitag, int bx);
int BuildObject(short nSprite, int nOjectType, int nHitag);
int BuildArrow(int nSprite, int nVal);
int BuildFireBall(int nSprite, int a, int b);
void BuildDrip(int nSprite);
int BuildEnergyBlock(short nSector);
int BuildElevC(int arg1, int nChannel, int nSector, int nWallSprite, int arg5, int arg6, int nCount, int zList ...);
int BuildElevF(int nChannel, int nSector, int nWallSprite, int arg_4, int arg_5, int nCount, int zList ...);
int BuildWallFace(short nChannel, short nWall, short nCount, int nPics ...);
int BuildSlide(int nChannel, int edx, int ebx, int ecx, int arg1, int arg2, int arg3);
#endif

View file

@ -0,0 +1,2 @@
#include "paul.h"

View file

@ -0,0 +1,7 @@
#ifndef __paul_h__
#define __paul_h__
#endif

File diff suppressed because it is too large Load diff

105
source/exhumed/src/player.h Normal file
View file

@ -0,0 +1,105 @@
#ifndef __player_h__
#define __player_h__
#include "typedefs.h"
void PlayerInterruptKeys();
void RestoreSavePoint(int nPlayer, int *x, int *y, int *z, short *nSector, short *nAngle);
void SetSavePoint(int nPlayer, int x, int y, int z, short nSector, short nAngle);
void InitPlayer();
void InitPlayerKeys(short nPlayer);
void DoKenTest();
int GrabPlayer();
void InitPlayerInventory(short nPlayer);
void RestartPlayer(short nPlayer);
void FuncPlayer(int nSector, int nSprite, int nRun);
#define kMaxPlayers 8
#define kDefaultLives 3
#define kMaxPlayerLives 5
#define kMaxHealth 800
extern int nLocalPlayer;
extern int lPlayerXVel;
extern int lPlayerYVel;
extern int nPlayerDAng;
struct Player
{
short nHealth;
short field_2;
short nAction;
short nSprite;
short bIsMummified;
short someNetVal;
short invincibility;
short nAir;
short nSeq;
short nMaskAmount;
ushort keys;
short nMagic;
char items[8];
short nAmmo[7]; // TODO - kMaxWeapons?
short pad[2];
short nCurrentWeapon;
short field_34;
short bIsFiring;
short field_38;
short field_3A;
short field_3C;
short nRun;
};
extern short PlayerCount;
extern short nPlayerTorch[];
extern short nPlayerLives[];
extern short nPlayerItem[];
extern Player PlayerList[];
extern short nPlayerInvisible[];
extern short nPlayerDouble[];
extern short nPlayerViewSect[];
extern short nPlayerFloorSprite[];
extern short nTauntTimer[];
extern short nDoppleSprite[];
extern ushort nPlayerWeapons[];
extern short nPlayerOldWeapon[];
extern short nPlayerGrenade[kMaxPlayers];
extern short nGrenadePlayer[50];
extern short nPistolClip[];
extern short nPlayerScore[];
extern short nPlayerClip[];
extern short bobangle;
extern int totalvel[];
extern short eyelevel[];
extern short nNetStartSprite[kMaxPlayers];
extern short nNetStartSprites;
extern short nCurStartSprite;
extern int nXDamage[kMaxPlayers];
extern int nYDamage[kMaxPlayers];
extern int nPlayerDY[kMaxPlayers];
extern int nPlayerDX[kMaxPlayers];
short GetPlayerFromSprite(short nSprite);
void SetPlayerMummified(int nPlayer, int bIsMummified);
int AddAmmo(int nPlayer, int nWeapon, int nAmmoAmount);
void ShootStaff(int nPlayer);
#endif

1601
source/exhumed/src/queen.cpp Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,13 @@
#ifndef __queen_h__
#define __queen_h__
void InitQueens();
int BuildQueen(int nSprite, int x, int y, int z, int nSector, int nAngle, int nVal);
void FuncQueenEgg(int, int, int);
void FuncQueenHead(int, int, int);
void FuncQueen(int, int, int);
#endif

276
source/exhumed/src/ra.cpp Normal file
View file

@ -0,0 +1,276 @@
#include "ra.h"
#include "runlist.h"
#include "engine.h"
#include "exhumed.h"
#include "player.h"
#include "move.h"
#include "sequence.h"
#include "input.h"
#include "gun.h"
#include "bullet.h"
#include <string.h>
/* bjd - the content of the ra.* files originally resided in gun.c I think... */
//#define kMaxRA 8
RA Ra[kMaxPlayers]; // one Ra for each player
short RaCount;
static actionSeq ActionSeq[] = {
{2, 1}, {0, 0}, {1, 0}, {2, 0}
};
void FreeRa(short nPlayer)
{
int nRun = Ra[nPlayer].field_4;
int nSprite = Ra[nPlayer].nSprite;
runlist_SubRunRec(nRun);
runlist_DoSubRunRec(sprite[nSprite].owner);
runlist_FreeRun(sprite[nSprite].lotag - 1);
mydeletesprite(nSprite);
}
int BuildRa(short nPlayer)
{
short nPlayerSprite = PlayerList[nPlayer].nSprite;
int nSprite = insertsprite(sprite[nPlayerSprite].sectnum, 203);
sprite[nSprite].cstat = 0x8000;
sprite[nSprite].xvel = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].extra = -1;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].hitag = 0;
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nPlayer | 0x210000);
sprite[nSprite].pal = 1;
sprite[nSprite].xrepeat = 64;
sprite[nSprite].yrepeat = 64;
sprite[nSprite].x = sprite[nPlayerSprite].x;
sprite[nSprite].y = sprite[nPlayerSprite].y;
sprite[nSprite].z = sprite[nPlayerSprite].z;
// GrabTimeSlot(3);
Ra[nPlayer].nSprite = nSprite;
Ra[nPlayer].field_4 = runlist_AddRunRec(NewRun, nPlayer | 0x210000);
Ra[nPlayer].nTarget = -1;
Ra[nPlayer].field_2 = 0;
Ra[nPlayer].field_0 = 0;
Ra[nPlayer].field_C = 0;
Ra[nPlayer].field_E = nPlayer;
return nPlayer | 0x210000;
}
void InitRa()
{
RaCount = 0;
memset(Ra, 0, sizeof(RA) * kMaxPlayers);
}
void MoveRaToEnemy(short nPlayer)
{
short nTarget = Ra[nPlayer].nTarget;
short nSprite = Ra[nPlayer].nSprite;
short field_0 = Ra[nPlayer].field_0;
if (nTarget != -1)
{
if (!(sprite[nTarget].cstat & 0x101) || sprite[nTarget].sectnum == kMaxSectors)
{
Ra[nPlayer].nTarget = -1;
if (!field_0 || field_0 == 3) {
return;
}
Ra[nPlayer].field_0 = 3;
Ra[nPlayer].field_2 = 0;
return;
}
else
{
if (sprite[nSprite].sectnum != sprite[nTarget].sectnum) {
mychangespritesect(nSprite, sprite[nTarget].sectnum);
}
}
}
else
{
if (field_0 == 1 || field_0 == 2)
{
Ra[nPlayer].field_0 = 3;
Ra[nPlayer].field_2 = 0;
return;
}
if (field_0) {
return;
}
sprite[nSprite].cstat = 0x8000;
nTarget = PlayerList[nPlayer].nSprite;
}
sprite[nSprite].x = sprite[nTarget].x;
sprite[nSprite].y = sprite[nTarget].y;
sprite[nSprite].z = sprite[nTarget].z - GetSpriteHeight(nTarget);
if (sprite[nSprite].sectnum != sprite[nTarget].sectnum) {
mychangespritesect(nSprite, sprite[nTarget].sectnum);
}
}
void FuncRa(int a, int nDamage, int nRun)
{
short nPlayer = RunData[nRun].nVal;
short nCurrentWeapon = PlayerList[nPlayer].nCurrentWeapon;
int var_14 = 0;
short edx = SeqOffsets[kSeqEyeHit] + ActionSeq[Ra[nPlayer].field_0].a;
short nSprite = Ra[nPlayer].nSprite;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
default:
{
DebugOut("unknown msg %d for Ra\n", a & 0x7F0000);
return;
}
case 0x30000:
case 0xA0000:
return;
case 0x20000:
{
Ra[nPlayer].nTarget = sPlayerInput[nPlayer].nTarget;
sprite[nSprite].picnum = seq_GetSeqPicnum2(edx, Ra[nPlayer].field_2);
if (Ra[nPlayer].field_0)
{
seq_MoveSequence(nSprite, edx, Ra[nPlayer].field_2);
Ra[nPlayer].field_2++;
if (Ra[nPlayer].field_2 >= SeqSize[edx])
{
Ra[nPlayer].field_2 = 0;
var_14 = 1;
}
}
switch (Ra[nPlayer].field_0)
{
case 0:
{
MoveRaToEnemy(nPlayer);
if (!Ra[nPlayer].field_C || Ra[nPlayer].nTarget <= -1)
{
sprite[nSprite].cstat = 0x8000;
}
else
{
sprite[nSprite].cstat &= 0x7FFF;
Ra[nPlayer].field_0 = 1;
Ra[nPlayer].field_2 = 0;
}
return;
}
case 1:
{
if (!Ra[nPlayer].field_C)
{
Ra[nPlayer].field_0 = 3;
Ra[nPlayer].field_2 = 0;
}
else
{
if (var_14) {
Ra[nPlayer].field_0 = 2;
}
MoveRaToEnemy(nPlayer);
}
return;
}
case 2:
{
MoveRaToEnemy(nPlayer);
if (nCurrentWeapon != kWeaponRing)
{
Ra[nPlayer].field_0 = 3;
Ra[nPlayer].field_2 = 0;
}
else
{
if (Ra[nPlayer].field_2 || Ra[nPlayer].nTarget <= -1)
{
if (!var_14) {
return;
}
Ra[nPlayer].field_0 = 3;
Ra[nPlayer].field_2 = 0;
}
else
{
if (PlayerList[nPlayer].nAmmo[kWeaponRing] > 0)
{
runlist_DamageEnemy(Ra[nPlayer].nTarget, PlayerList[Ra[nPlayer].field_E].nSprite, BulletInfo[kWeaponRing].nDamage);
AddAmmo(nPlayer, kWeaponRing, -WeaponInfo[kWeaponRing].d);
SetQuake(nSprite, 100);
}
else
{
Ra[nPlayer].field_0 = 3;
Ra[nPlayer].field_2 = 0;
SelectNewWeapon(nPlayer);
}
}
}
return;
}
case 3:
{
if (var_14)
{
sprite[nSprite].cstat |= 0x8000;
Ra[nPlayer].field_0 = 0;
Ra[nPlayer].field_2 = 0;
Ra[nPlayer].field_C = 0;
}
return;
}
default:
return;
}
}
case 0x90000:
{
short nSprite2 = a & 0xFFFF;
seq_PlotSequence(nSprite2, edx, Ra[nPlayer].field_2, 1);
tsprite[nSprite2].owner = -1;
return;
}
}
}

25
source/exhumed/src/ra.h Normal file
View file

@ -0,0 +1,25 @@
#ifndef __ra_h__
#define __ra_h__
struct RA
{
short field_0;
short field_2;
short field_4;
short nSprite;
short nTarget;
short field_A;
short field_C;
short field_E;
};
extern RA Ra[];
void FreeRa(short nPlayer);
int BuildRa(short nPlayer);
void InitRa();
void MoveRaToEnemy(short nPlayer);
void FuncRa(int, int, int);
#endif

View file

@ -0,0 +1,63 @@
#include "random.h"
int randA = 0;
int randB = 0x11111111;
int randC = 0x1010101;
void InitRandom()
{
randA = 0;
randB = 0x11111111;
randC = 0x1010101;
}
// TODO - checkme
int RandomBit()
{
randA = (randA >> 1) | (((randA ^ ((randA >> 1) ^ (randA >> 2) ^ (randA >> 31) ^ (randA >> 6) ^ (randA >> 4))) & 1) << 31);
randB = (randB >> 1) | ((((randB >> 2) ^ (randB >> 30)) & 1) << 30);
randC = (randC >> 1) | ((((randC >> 1) ^ (randC >> 28)) & 1) << 28);
return ((randA == 0) & randC | (randB & randA)) & 1;
}
char RandomByte()
{
char randByte = RandomBit() << 7;
randByte |= RandomBit() << 6;
randByte |= RandomBit() << 5;
randByte |= RandomBit() << 4;
randByte |= RandomBit() << 3;
randByte |= RandomBit() << 2;
randByte |= RandomBit() << 1;
randByte |= RandomBit();
return randByte;
}
short RandomWord()
{
short randWord = RandomByte() << 8;
randWord |= RandomByte();
return randWord;
}
long RandomLong()
{
long randLong = RandomWord() << 16;
randLong |= RandomWord();
return randLong;
}
int RandomSize(int nSize)
{
int randSize = 0;
while (nSize > 0)
{
randSize = randSize * 2 | RandomBit();
nSize--;
}
return randSize;
}

View file

@ -0,0 +1,12 @@
#ifndef __random_h__
#define __random_h__
void InitRandom();
int RandomBit();
char RandomByte();
short RandomWord();
long RandomLong();
int RandomSize(int nSize);
#endif

383
source/exhumed/src/rat.cpp Normal file
View file

@ -0,0 +1,383 @@
#include "engine.h"
#include "rat.h"
#include "sequence.h"
#include "runlist.h"
#include "random.h"
#include "view.h"
#include "init.h"
#include "exhumed.h"
#include "move.h"
#include <assert.h>
#define kMaxRats 50
short nMinChunk;
short nPlayerPic; // why is this here?
short nRatCount;
short nMaxChunk;
struct Rat
{
short a;
short nAction;
short nSprite;
short d;
short nTarget;
short f;
short g;
short _pad;
};
Rat RatList[kMaxRats];
static actionSeq ActionSeq[] = { { 0, 1}, {1, 0}, {1, 0}, {9, 1}, {0, 1} };
void InitRats()
{
nRatCount = 0;
nMinChunk = 9999;
nMaxChunk = -1;
for (int i = 122; i < 131; i++)
{
int nPic = seq_GetSeqPicnum(kSeqJoe, i, 0);
if (nPic < nMinChunk)
nMinChunk = nPic;
if (nPic > nMaxChunk)
nMaxChunk = nPic;
}
nPlayerPic = seq_GetSeqPicnum(kSeqJoe, 120, 0);
}
void SetRatVel(short nSprite)
{
sprite[nSprite].xvel = (short)Sin(sprite[nSprite].ang + 512) >> 2;
sprite[nSprite].yvel = (short)Sin(sprite[nSprite].ang) >> 2;
}
int BuildRat(short nSprite, int x, int y, int z, short nSector, int nAngle)
{
if (nRatCount >= kMaxRats) {
return -1;
}
short nRat = nRatCount++;
if (nSprite < 0)
{
nSprite = insertsprite(nSector, 108);
assert(nSprite >= 0 && nSprite < kMaxSprites);
sprite[nSprite].x = x;
sprite[nSprite].y = y;
sprite[nSprite].z = z;
}
else
{
sprite[nSprite].ang = nAngle;
changespritestat(nSprite, 108);
}
sprite[nSprite].cstat = 0x101;
sprite[nSprite].shade = -12;
sprite[nSprite].xoffset = 0;
sprite[nSprite].yoffset = 0;
sprite[nSprite].picnum = 1;
sprite[nSprite].pal = sector[sprite[nSprite].sectnum].ceilingpal;
sprite[nSprite].clipdist = 30;
sprite[nSprite].ang = nAngle;
sprite[nSprite].xrepeat = 50;
sprite[nSprite].yrepeat = 50;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
sprite[nSprite].zvel = 0;
sprite[nSprite].lotag = runlist_HeadRun() + 1;
sprite[nSprite].hitag = 0;
sprite[nSprite].extra = -1;
if (nAngle >= 0) {
RatList[nRat].nAction = 2;
}
else {
RatList[nRat].nAction = 4;
}
RatList[nRat].a = 0;
RatList[nRat].nSprite = nSprite;
RatList[nRat].nTarget = -1;
RatList[nRat].f = RandomSize(5);
RatList[nRat].g = RandomSize(3);
sprite[nSprite].owner = runlist_AddRunRec(sprite[nSprite].lotag - 1, nRat | 0x240000);
RatList[nRat].d = runlist_AddRunRec(NewRun, nRat | 0x240000);
return 0;
}
int FindFood(short nSprite)
{
short nSector = sprite[nSprite].sectnum;
int x = sprite[nSprite].x;
int y = sprite[nSprite].y;
int z = sprite[nSprite].z;
int z2 = z + sector[nSector].ceilingz;
if (nChunkTotal)
{
int nSprite2 = nChunkSprite[RandomSize(7) % nChunkTotal];
if (nSprite2 != -1)
{
if (cansee(x, y, z2, nSector, sprite[nSprite2].x, sprite[nSprite2].y, sprite[nSprite2].z, sprite[nSprite2].sectnum)) {
return nSprite2;
}
}
}
if (!nBodyTotal) {
return -1;
}
int nSprite2 = nChunkSprite[RandomSize(7) % nBodyTotal];
if (nSprite2 != -1)
{
if (nPlayerPic == sprite[nSprite2].picnum)
{
if (cansee(x, y, z, nSector, sprite[nSprite2].x, sprite[nSprite2].y, sprite[nSprite2].z, sprite[nSprite2].sectnum)) {
return nSprite2;
}
}
}
return -1;
}
void FuncRat(int a, int nDamage, int nRun)
{
short nRat = RunData[nRun].nVal;
short nSprite = RatList[nRat].nSprite;
short nAction = RatList[nRat].nAction;
int var_20 = 0;
int nMessage = a & 0x7F0000;
switch (nMessage)
{
default:
{
DebugOut("unknown msg %d for Rathead\n", nMessage);
return;
}
case 0xA0000:
{
nDamage = runlist_CheckRadialDamage(nSprite);
// fall through to 0x80000
}
case 0x80000:
{
if (nDamage)
{
sprite[nSprite].cstat = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
RatList[nRat].nAction = 3;
RatList[nRat].a = 0;
}
break;
}
case 0x90000:
{
seq_PlotSequence(a, SeqOffsets[kSeqRat] + ActionSeq[nAction].a, RatList[nRat].a, ActionSeq[nAction].b);
return;
}
case 0x20000:
{
int nSeq = SeqOffsets[kSeqRat] + ActionSeq[nAction].a;
sprite[nSprite].picnum = seq_GetSeqPicnum2(nSeq, RatList[nRat].a);
seq_MoveSequence(nSprite, nSeq, RatList[nRat].a);
RatList[nRat].a++;
if (RatList[nRat].a >= SeqSize[nSeq])
{
var_20 = 1;
RatList[nRat].a = 0;
}
short nTarget = RatList[nRat].nTarget;
Gravity(nSprite);
switch (nAction)
{
default:
{
return;
}
case 0:
{
RatList[nRat].f--;
if (RatList[nRat].f > 0) {
return;
}
int xVal = sprite[nSprite].x - sprite[nTarget].x;
if (xVal < 0) {
xVal = -xVal;
}
int yVal = sprite[nSprite].y - sprite[nTarget].y;
if (yVal < 0) {
yVal = -yVal;
}
if (xVal > 50 || yVal > 50)
{
RatList[nRat].nAction = 2;
RatList[nRat].a = 0;
RatList[nRat].nTarget = -1;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
return;
}
RatList[nRat].a ^= 1;
RatList[nRat].f = RandomSize(5) + 4;
RatList[nRat].g--;
if (RatList[nRat].g <= 0)
{
short nFoodSprite = FindFood(nSprite);
if (nFoodSprite == -1) {
return;
}
RatList[nRat].nTarget = nFoodSprite;
PlotCourseToSprite(nSprite, nFoodSprite);
SetRatVel(nSprite);
RatList[nRat].nAction = 1;
RatList[nRat].g = 900;
RatList[nRat].a = 0;
}
return;
}
case 1:
{
RatList[nRat].g--;
if (RatList[nRat].g <= 0)
{
RatList[nRat].nAction = 2;
RatList[nRat].a = 0;
sprite[nSprite].yvel = 0;
RatList[nRat].nTarget = -1;
sprite[nSprite].xvel = 0;
}
MoveCreature(nSprite);
int xVal = sprite[nSprite].x - sprite[nTarget].x;
if (xVal < 0) {
xVal = -xVal;
}
int yVal = sprite[nSprite].y - sprite[nTarget].y;
if (yVal < 0) {
yVal = -yVal;
}
if (xVal >= 50 || yVal >= 50)
{
RatList[nRat].f--;
if (RatList[nRat].f < 0)
{
PlotCourseToSprite(nSprite, nTarget);
SetRatVel(nSprite);
RatList[nRat].f = 32;
}
return;
}
RatList[nRat].nAction = 0;
RatList[nRat].a = 0;
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
RatList[nRat].g = RandomSize(3);
return;
}
case 2:
{
if (sprite[nSprite].xvel | sprite[nSprite].yvel | sprite[nSprite].zvel) {
MoveCreature(nSprite);
}
RatList[nRat].f--;
if (RatList[nRat].f <= 0)
{
RatList[nRat].nTarget = FindFood(nSprite);
if (RatList[nRat].nTarget <= -1)
{
RatList[nRat].f = RandomSize(6);
if (sprite[nSprite].xvel | sprite[nSprite].yvel)
{
sprite[nSprite].yvel = 0;
sprite[nSprite].xvel = 0;
return;
}
sprite[nSprite].ang = RandomSize(11);
SetRatVel(nSprite);
return;
}
else
{
PlotCourseToSprite(nSprite, RatList[nRat].nTarget);
SetRatVel(nSprite);
RatList[nRat].nAction = 1;
RatList[nRat].g = 900;
RatList[nRat].a = 0;
return;
}
}
return;
}
case 3:
{
if (var_20 != 0)
{
runlist_DoSubRunRec(sprite[nSprite].owner);
runlist_FreeRun(sprite[nSprite].lotag - 1);
runlist_SubRunRec(RatList[nRat].d);
sprite[nSprite].cstat = 0x8000;
mydeletesprite(nSprite);
}
return;
}
}
break;
}
}
}

11
source/exhumed/src/rat.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef __rat_h__
#define __rat_h__
void InitRats();
void SetRatVel(short nSprite);
int BuildRat(short nSprite, int x, int y, int z, short nSector, int nAngle);
int FindFood(short nSprite);
void FuncRat(int a, int b, int nRun);
#endif

View file

@ -0,0 +1,152 @@
#include "record.h"
#include "typedefs.h"
#include "save.h"
#include <stdio.h>
#include <string.h>
short record_mode = 0;
int record_limit = -1;
int record_index = 16384;
uchar record_buffer[16384];
FILE *record_file;
struct RecordHeader
{
char signature[4];
short b;
};
RecordHeader record_head;
BYTE GetRecord()
{
if (record_index >= 16384)
{
record_index = 0;
int nRead = fread(record_buffer, 1, 16384, record_file);
if (nRead < 16384) {
record_limit = 16384;
}
else {
record_limit = -1;
}
}
if (record_limit > 0)
{
if (record_limit <= record_index)
{
record_mode = 3;
}
}
return record_buffer[record_index++];
}
void PutRecord(BYTE record)
{
BYTE val_10 = record;
if (record_index >= 16384)
{
record_index = 0;
fwrite(record_buffer, 16384, 1, record_file);
}
record_buffer[record_index++] = val_10;
}
int OpenRecord(const char *filename, short *edx)
{
record_file = fopen(filename, "rb");
if (record_file)
{
if (!fread(&record_head, sizeof(record_head), 1, record_file)) {
return 0;
}
if (memcmp(record_head.signature, "LOBO", 4) == 0) {
return 0;
}
*edx = record_head.b;
record_index = 16384;
record_limit = -1;
record_mode = 2;
return 1;
}
else
{
record_file = fopen(filename, "wb");
if (!record_file) {
return 0;
}
strncpy(record_head.signature, "LOBO", 4);
record_head.b = *edx;
if (!fwrite(&record_head, sizeof(record_head), 1, record_file)) {
return 0;
}
record_index = 0;
record_limit = -1;
record_mode = 1;
return 1;
}
}
int ExecRecord(BYTE *pRecord, int nSize)
{
if (record_mode == 2)
{
for (int i = 0; i < nSize; i++)
{
pRecord[i] = GetRecord();
}
}
else if (record_mode == 1)
{
for (int i = 0; i < nSize; i++)
{
PutRecord(pRecord[i]);
}
}
if (record_mode == 3) {
return 0;
}
else {
return 1;
}
}
int CloseRecord()
{
if (record_mode == 1)
{
loadgame(0);
if (record_index)
{
if (!fwrite(record_buffer, record_index, 1, record_file)) {
return 0;
}
}
}
else if (record_mode == 2 || record_mode == 3)
{
loadgame(1);
}
fclose(record_file);
return 1;
}

Some files were not shown because too many files have changed in this diff Show more