123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836 |
- #include <stdio.h>
- #include <string.h>
- #include "engine.h"
- #include "bstub.h"
- #include "build.h"
- #include "misc.h"
- #include "trig.h"
- #include "globals.h"
- #include "textio.h"
- #include "gameutil.h"
- #include "db.h"
- #include "debug4g.h"
- #include "key.h"
- #include "edit2d.h"
- enum controlType
- {
- TEXT,
- NUMBER,
- CHECKBOX,
- RADIOBUTTON,
- LIST,
- DIALOG
- };
- typedef struct DIALOG_ITEM *ITEM_PTR;
- typedef BYTE ( *ITEM_PROC )( ITEM_PTR, BYTE key );
- struct DIALOG_ITEM
- {
- int x, y;
- int tabGroup;
- enum controlType type;
- char *label;
- int minValue;
- int maxValue;
- char **names;
- ITEM_PROC fieldHelpProc;
- int value;
- };
- // dialog helper function prototypes
- BYTE GetNextUnusedID( DIALOG_ITEM *control, BYTE key );
- BYTE DoSectorFXDialog( DIALOG_ITEM *control, BYTE key );
- /*******************************************************************************
- Local Variables
- *******************************************************************************/
- static char buffer[256] = "";
- short sectorhighlight; // which sector mouse is inside in 2d mode
- DIALOG_ITEM dlgSprite[] =
- {
- { 0, 0, 1, LIST, "Type %4d: %-18.18s", 0, 1023, gSpriteNames }, // 0
- { 0, 1, 2, NUMBER, "RX ID: %4d", 0, 1023, NULL, GetNextUnusedID }, // 1
- { 0, 2, 3, NUMBER, "TX ID: %4d", 0, 1023, NULL, GetNextUnusedID }, // 2
- { 0, 3, 4, LIST, "State %1d: %-3.3s", 0, 1, gBoolNames }, // 3
- { 0, 4, 5, LIST, "Cmd: %3d: %-6.6s", 0, 255, gCommandNames }, // 4
- { 0, 5, 0, TEXT, "Send when:" }, // 5
- { 0, 6, 6, CHECKBOX, "going ON" }, // 6
- { 0, 7, 7, CHECKBOX, "going OFF" }, // 7
- { 0, 8, 8, NUMBER, "busyTime = %4d", 0, 4095 }, // 8
- { 0, 9, 9, NUMBER, "waitTime = %4d", 0, 4095 }, // 9
- { 0, 10, 10, LIST, "restState %1d: %-3.3s", 0, 1, gBoolNames }, // 10
- { 30, 0, 0, TEXT, "Trigger On:" }, // 11
- { 30, 1, 11, CHECKBOX, "Push" }, // 12
- { 30, 2, 12, CHECKBOX, "Impact" }, // 13
- { 30, 3, 13, CHECKBOX, "Reserved" }, // 14
- { 30, 4, 14, CHECKBOX, "Pickup" }, // 15
- { 30, 5, 15, CHECKBOX, "Touch" }, // 16
- { 30, 6, 16, CHECKBOX, "Sight" }, // 17
- { 30, 7, 17, CHECKBOX, "Proximity" }, // 18
- { 46, 0, 0, TEXT, "Trigger Flags:" }, // 19
- { 46, 1, 18, CHECKBOX, "Decoupled" }, // 20
- { 46, 2, 19, CHECKBOX, "1-shot" }, // 21
- { 46, 3, 20, CHECKBOX, "Locked" }, // 22
- { 46, 4, 21, CHECKBOX, "Interruptable" }, // 23
- { 46, 5, 22, NUMBER, "Data1: %5d", 0, 65535 }, // 24
- { 46, 6, 23, NUMBER, "Data2: %5d", 0, 65535 }, // 25
- { 46, 7, 24, NUMBER, "Data3: %5d", 0, 65535 }, // 26
- { 46, 8, 25, NUMBER, "Key: %1d", 0, 7 }, // 27
- { 46, 9, 26, NUMBER, "Sound: %3d", 0, 255 }, // 28
- { 46, 10, 27, NUMBER, "Difficulty: %1d", 0, 3 }, // 29
- { 62, 0, 0, TEXT, "Respawn:" }, // 30
- { 62, 1, 28, LIST, "When %1d: %-6.6s", 0, 3, gRespawnNames }, // 31
- { 62, 2, 29, NUMBER, "Time = %4d", 0, 4095 }, // 32
- { 62, 4, 0, TEXT, "Dude Flags:" }, // 33
- { 62, 5, 30, CHECKBOX, "dudeDeaf" }, // 34
- { 62, 6, 31, CHECKBOX, "dudeAmbush" }, // 35
- { 62, 7, 32, CHECKBOX, "dudeGuard" }, // 36
- { 62, 8, 33, CHECKBOX, "reserved" }, // 37
- };
- DIALOG_ITEM dlgWall[] =
- {
- { 0, 0, 1, LIST, "Type %4d: %-18.18s", 0, 1023, gWallNames }, // 0
- { 0, 1, 2, NUMBER, "RX ID: %4d", 0, 1023, NULL, GetNextUnusedID }, // 1
- { 0, 2, 3, NUMBER, "TX ID: %4d", 0, 1023, NULL, GetNextUnusedID }, // 2
- { 0, 3, 4, LIST, "State %1d: %-3.3s", 0, 1, gBoolNames }, // 3
- { 0, 4, 5, LIST, "Cmd: %3d: %-6.6s", 0, 255, gCommandNames }, // 4
- { 0, 5, 0, TEXT, "Send when:" }, // 5
- { 0, 6, 6, CHECKBOX, "going ON" }, // 6
- { 0, 7, 7, CHECKBOX, "going OFF" }, // 7
- { 0, 8, 8, NUMBER, "busyTime = %4d", 0, 4095 }, // 8
- { 0, 9, 9, NUMBER, "waitTime = %4d", 0, 4095 }, // 9
- { 0, 10, 10, LIST, "restState %1d: %-3.3s", 0, 1, gBoolNames }, // 10
- { 30, 0, 0, TEXT, "Trigger On:" }, // 11
- { 30, 1, 11, CHECKBOX, "Push" }, // 12
- { 30, 2, 12, CHECKBOX, "Impact" }, // 13
- { 30, 3, 13, CHECKBOX, "Reserved" }, // 14
- { 46, 0, 0, TEXT, "Trigger Flags:" }, // 15
- { 46, 1, 14, CHECKBOX, "Decoupled" }, // 16
- { 46, 2, 15, CHECKBOX, "1-shot" }, // 17
- { 46, 3, 16, CHECKBOX, "Locked" }, // 18
- { 46, 4, 17, CHECKBOX, "Interruptable" }, // 19
- { 46, 6, 18, NUMBER, "Data: %5d", 0, 65535 }, // 20
- { 46, 7, 19, NUMBER, "Key: %1d", 0, 7 }, // 21
- { 46, 8, 20, NUMBER, "panX = %4d", -128, 127 }, // 22
- { 46, 9, 21, NUMBER, "panY = %4d", -128, 127 }, // 23
- { 46, 10, 22, CHECKBOX, "panAlways" }, // 24
- };
- DIALOG_ITEM dlgSectorFX[] =
- {
- { 0, 0, 0, TEXT, "Lighting:" }, // 0
- { 0, 1, 1, LIST, "Wave: %1d %-9.9s", 0, 15, gWaveNames }, // 1
- { 0, 2, 2, NUMBER, "Amplitude: %+4d", -128, 127 }, // 2
- { 0, 3, 3, NUMBER, "Freq: %3d", 0, 255 }, // 3
- { 0, 4, 4, NUMBER, "Phase: %3d", 0, 255 }, // 4
- { 0, 5, 5, CHECKBOX, "floor" }, // 5
- { 0, 6, 6, CHECKBOX, "ceiling" }, // 6
- { 0, 7, 7, CHECKBOX, "walls" }, // 7
- { 0, 8, 8, CHECKBOX, "shadeAlways" }, // 8
- { 20, 0, 0, TEXT, "Motion FX:" }, // 9
- { 20, 1, 9, NUMBER, "Speed = %4d", 0, 255 }, // 10
- { 20, 2, 10, NUMBER, "Angle = %4d", 0, kAngle360-1 }, // 11
- { 20, 3, 11, CHECKBOX, "pan floor" }, // 12
- { 20, 4, 12, CHECKBOX, "pan ceiling" }, // 13
- { 20, 5, 13, CHECKBOX, "panAlways" }, // 14
- { 20, 6, 14, CHECKBOX, "drag" }, // 15
- { 35, 2, 15, LIST, "Depth = %1d: %-5.5s", 0, 3, gDepthNames }, // 16
- { 35, 3, 16, LIST, "Under = %1d: %-3.3s", 0, 1, gBoolNames }, // 17
- { 35, 4, 17, LIST, "Wind = %1d: %-3.3s", 0, 1, gBoolNames}, // 18
- };
- DIALOG_ITEM dlgSector[] =
- {
- { 0, 0, 1, LIST, "Type %4d: %-18.18s", 0, 1023, gSectorNames }, // 0
- { 0, 1, 2, NUMBER, "RX ID: %4d", 0, 1023, NULL, GetNextUnusedID }, // 1
- { 0, 2, 3, NUMBER, "TX ID: %4d", 0, 1023, NULL, GetNextUnusedID }, // 2
- { 0, 3, 4, LIST, "State %1d: %-3.3s", 0, 1, gBoolNames }, // 3
- { 0, 4, 5, LIST, "Cmd: %3d: %-6.6s", 0, 255, gCommandNames }, // 4
- { 0, 5, 0, TEXT, "Send when:" }, // 5
- { 0, 6, 6, CHECKBOX, "going ON" }, // 6
- { 0, 7, 7, CHECKBOX, "going OFF" }, // 7
- { 0, 8, 8, NUMBER, "busyTime = %3d", 0, 255 }, // 8
- { 0, 9, 9, NUMBER, "waitTime = %3d", 0, 255 }, // 9
- { 0, 10, 10, LIST, "restState %1d: %-3.3s", 0, 1, gBoolNames }, // 10
- { 30, 0, 0, TEXT, "Trigger On:" }, // 11
- { 30, 1, 11, CHECKBOX, "Push" }, // 12
- { 30, 2, 12, CHECKBOX, "Impact" }, // 13
- { 30, 3, 13, CHECKBOX, "Reserved" }, // 14
- { 30, 4, 14, CHECKBOX, "Enter" }, // 15
- { 30, 5, 15, CHECKBOX, "Exit" }, // 16
- { 30, 6, 16, CHECKBOX, "WallPush" }, // 17
- { 46, 0, 0, TEXT, "Trigger Flags:" }, // 18
- { 46, 1, 17, CHECKBOX, "Decoupled" }, // 19
- { 46, 2, 18, CHECKBOX, "1-shot" }, // 20
- { 46, 3, 19, CHECKBOX, "Locked" }, // 21
- { 46, 4, 20, CHECKBOX, "Interruptable" }, // 22
- { 46, 6, 21, NUMBER, "Data: %5d", 0, 65535 }, // 23
- { 46, 7, 22, NUMBER, "Key: %1d", 0, 7 }, // 24
- { 65, 10, 23, DIALOG, "EFFECTS...", 0, 0, NULL, DoSectorFXDialog }, // 25
- };
- void DialogText( int x, int y, short nFore, short nBack, char *string)
- {
- printext16(x * 8 + 4, y * 8 + 28, nFore, nBack, string, 0);
- }
- /***********************************************************************
- * PaintDialogItem()
- *
- **********************************************************************/
- void PaintDialogItem(DIALOG_ITEM *control, int focus)
- {
- short foreColor = 11, backColor = 8;
- if ( focus )
- {
- foreColor = 14;
- backColor = 0;
- }
- if (control->tabGroup == 0)
- {
- foreColor = 15;
- backColor = 2;
- }
- switch ( control->type )
- {
- case TEXT:
- case DIALOG:
- DialogText(control->x, control->y, foreColor, backColor, control->label);
- break;
- case NUMBER:
- sprintf(buffer, control->label, control->value);
- DialogText(control->x, control->y, foreColor, backColor, buffer);
- break;
- case LIST:
- dassert(control->names != NULL);
- sprintf(buffer, control->label, control->value, control->names[control->value]);
- DialogText(control->x, control->y, foreColor, backColor, buffer);
- break;
- case CHECKBOX:
- sprintf(buffer, "%c %s", control->value ? 3 : 2, control->label);
- DialogText(control->x, control->y, foreColor, backColor, buffer);
- break;
- case RADIOBUTTON:
- sprintf(buffer, "%c %s", control->value ? 5 : 4, control->label);
- DialogText(control->x, control->y, foreColor, backColor, buffer);
- break;
- }
- }
- /***********************************************************************
- * PaintDialog()
- *
- **********************************************************************/
- void PaintDialog(DIALOG_ITEM *dialog, int count)
- {
- int i;
- clearmidstatbar16();
- for ( i = 0; i < count; i++ )
- {
- PaintDialogItem(&dialog[i], kFalse);
- }
- }
- /***********************************************************************
- * FindGroup()
- *
- **********************************************************************/
- DIALOG_ITEM *FindGroup(DIALOG_ITEM *dialog, int count, int group)
- {
- DIALOG_ITEM *control;
- for ( control = dialog; control < &dialog[count]; control++)
- {
- if ( control->tabGroup == group )
- break;
- }
- dassert(control < &dialog[count]);
- if ( control->type == RADIOBUTTON )
- {
- while ( control->value == kFalse )
- {
- control++;
- dassert(control < &dialog[count]);
- dassert(control->type == RADIOBUTTON);
- }
- }
- return control;
- }
- /***********************************************************************
- * SetControlValue()
- *
- **********************************************************************/
- void SetControlValue(DIALOG_ITEM *dialog, int count, int group, int value )
- {
- int i;
- for ( i = 0; i < count; i++)
- {
- if ( dialog[i].tabGroup == group )
- break;
- }
- dassert(i < count);
- dialog[i].value = value;
- }
- /***********************************************************************
- * GetControlValue()
- *
- **********************************************************************/
- int GetControlValue(DIALOG_ITEM *dialog, int count, int group )
- {
- int i;
- int value = 0;
- for ( i = 0; i < count; i++)
- {
- if ( dialog[i].tabGroup == group )
- break;
- }
- dassert(i < count);
- return dialog[i].value;
- }
- /***********************************************************************
- * SetRadioButton()
- *
- **********************************************************************/
- void SetRadioButton(DIALOG_ITEM *dialog, int count, int group, int value )
- {
- int i;
- for ( i = 0; i < count; i++)
- {
- if ( dialog[i].tabGroup == group )
- break;
- }
- dassert(i < count);
- while ( i < count && dialog[i].tabGroup == group )
- {
- dialog[i].value = (value == 0);
- i++;
- value--;
- }
- dassert(value < 0);
- }
- /***********************************************************************
- * GetRadioButton()
- *
- **********************************************************************/
- int GetRadioButton(DIALOG_ITEM *dialog, int count, int group )
- {
- int i;
- int value = 0;
- for ( i = 0; i < count; i++)
- {
- if ( dialog[i].tabGroup == group )
- break;
- }
- dassert(i < count);
- while ( i < count )
- {
- dassert(dialog[i].type == RADIOBUTTON);
- if ( dialog[i].value )
- break;
- i++;
- value++;
- }
- dassert(i < count);
- return value;
- }
- /*******************************************************************************
- FUNCTION: EditDialog()
- DESCRIPTION: This is the editing event loop for dialogs.
- PARAMETERS: dialog is a pointer to the first control, count is the
- number of controls within the dialog.
- RETURNS: 1 if exited via Enter, 0 if exited with Esc
- *******************************************************************************/
- int EditDialog(DIALOG_ITEM *dialog, int count)
- {
- int group = 1, lastGroup = 0;
- int i, value, oldValue;
- DIALOG_ITEM *control;
- BYTE key = 0;
- keyFlushStream();
- PaintDialog(dialog, count);
- for ( i = 0; i < count; i++ )
- {
- if ( dialog[i].tabGroup > lastGroup )
- lastGroup = dialog[i].tabGroup;
- }
- control = FindGroup(dialog, count, group);
- while ( 1 )
- {
- PaintDialogItem(control, kTrue);
- do
- {
- key = keyGet();
- } while ( key == 0 );
- if ( control->fieldHelpProc )
- {
- key = control->fieldHelpProc(control, key);
- // may need to repaint all in case of subdialogs
- PaintDialog(dialog, count);
- }
- switch ( key )
- {
- case KEY_ENTER:
- case KEY_PADENTER:
- keystatus[key] = 0; // need to clear in 2D mode, got it?
- BeepOkay();
- return 1;
- case KEY_ESC:
- keystatus[key] = 0;
- return 0;
- case KEY_LEFT:
- if ( --group == 0 )
- group = lastGroup;
- PaintDialogItem(control, kFalse);
- control = FindGroup(dialog, count, group);
- break;
- case KEY_RIGHT:
- if ( ++group > lastGroup )
- group = 1;
- PaintDialogItem(control, kFalse);
- control = FindGroup(dialog, count, group);
- break;
- case KEY_TAB:
- if ( keystatus[KEY_LSHIFT] || keystatus[KEY_RSHIFT] )
- {
- if ( --group == 0 )
- group = lastGroup;
- PaintDialogItem(control, kFalse);
- control = FindGroup(dialog, count, group);
- break;
- }
- else
- {
- if ( ++group > lastGroup )
- group = 1;
- PaintDialogItem(control, kFalse);
- control = FindGroup(dialog, count, group);
- break;
- }
- default:
- switch ( control->type )
- {
- case NUMBER:
- oldValue = control->value;
- switch ( key )
- {
- case KEY_BACKSPACE:
- control->value /= 10;
- break;
- case KEY_PADPLUS:
- case KEY_UP:
- control->value++;
- break;
- case KEY_PADMINUS:
- case KEY_DOWN:
- control->value--;
- break;
- case KEY_PAGEUP:
- control->value = IncBy(control->value, 10);
- break;
- case KEY_PAGEDN:
- control->value = DecBy(control->value, 10);
- break;
- default:
- key = ScanToAscii[key];
- if ( key >= '0' && key <= '9' )
- control->value = control->value * 10 + key - '0';
- }
- if ( control->value > control->maxValue )
- control->value = control->maxValue;
- if ( control->value < control->minValue )
- control->value = control->minValue;
- break;
- case CHECKBOX:
- switch ( key )
- {
- case KEY_SPACE:
- control->value = !control->value;
- break;
- }
- break;
- case RADIOBUTTON:
- PaintDialogItem(control, kFalse);
- switch ( key )
- {
- case KEY_UP:
- control->value = kFalse;
- PaintDialogItem(control, kFalse);
- do
- {
- if (--control < dialog)
- control = &dialog[count - 1];
- } while ( control->tabGroup != group );
- control->value = kTrue;
- break;
- case KEY_DOWN:
- control->value = kFalse;
- PaintDialogItem(control, kFalse);
- do
- {
- if (++control == &dialog[count])
- control = dialog;
- } while ( control->tabGroup != group );
- control->value = kTrue;
- break;
- }
- break;
- case LIST:
- oldValue = control->value;
- value = control->value;
- switch ( key )
- {
- case KEY_PADPLUS:
- case KEY_UP:
- do
- {
- value++;
- } while ( value <= control->maxValue && control->names[value] == NULL );
- break;
- case KEY_PADMINUS:
- case KEY_DOWN:
- do
- {
- value--;
- } while ( value >= control->minValue && control->names[value] == NULL );
- break;
- case KEY_PAGEUP:
- do
- {
- value = IncBy(value, 10);
- } while ( value <= control->maxValue && control->names[value] == NULL );
- break;
- case KEY_PAGEDN:
- do
- {
- value = DecBy(value, 10);
- } while ( value >= control->minValue && control->names[value] == NULL );
- break;
- }
- if ( value >= control->minValue && value <= control->maxValue && control->names[value] != NULL )
- control->value = value;
- break;
- }
- }
- }
- }
- BYTE GetNextUnusedID( DIALOG_ITEM *control, BYTE key )
- {
- BOOL used[1024];
- int i;
- switch ( key )
- {
- case KEY_F10:
- memset(used, FALSE, sizeof(used));
- for (i = 0; i < numsectors; i++)
- {
- int nXSector = sector[i].extra;
- if ( nXSector > 0 )
- {
- used[xsector[nXSector].txID] = TRUE;
- used[xsector[nXSector].rxID] = TRUE;
- }
- }
- for (i = 0; i < numwalls; i++)
- {
- int nXWall = wall[i].extra;
- if ( nXWall > 0 )
- {
- used[xwall[nXWall].txID] = TRUE;
- used[xwall[nXWall].rxID] = TRUE;
- }
- }
- for (i = 0; i < kMaxSprites; i++)
- {
- if ( sprite[i].statnum < kMaxStatus )
- {
- int nXSprite = sprite[i].extra;
- if ( nXSprite > 0 )
- {
- used[xsprite[nXSprite].txID] = TRUE;
- used[xsprite[nXSprite].rxID] = TRUE;
- }
- }
- }
- // find the first unused id
- for (i = 100; i < 1024; i++)
- if ( !used[i] )
- break;
- control->value = i;
- return 0;
- }
- return key;
- }
- BYTE DoSectorFXDialog( DIALOG_ITEM * /* control */, BYTE key )
- {
- switch ( key )
- {
- case KEY_ENTER:
- if ( EditDialog(dlgSectorFX, LENGTH(dlgSectorFX)) )
- return KEY_ENTER;
- return 0;
- }
- return key;
- }
- /***********************************************************************
- * XWallToDialog()
- *
- **********************************************************************/
- void XWallToDialog( int nWall )
- {
- int nXWall = wall[nWall].extra;
- dassert(nXWall > 0 && nXWall < kMaxXWalls);
- dlgWall[0].value = wall[nWall].type;
- dlgWall[1].value = xwall[nXWall].rxID;
- dlgWall[2].value = xwall[nXWall].txID;
- dlgWall[3].value = xwall[nXWall].state;
- dlgWall[4].value = xwall[nXWall].command;
- dlgWall[6].value = xwall[nXWall].triggerOn;
- dlgWall[7].value = xwall[nXWall].triggerOff;
- dlgWall[8].value = xwall[nXWall].busyTime;
- dlgWall[9].value = xwall[nXWall].waitTime;
- dlgWall[10].value = xwall[nXWall].restState;
- dlgWall[12].value = xwall[nXWall].triggerPush;
- dlgWall[13].value = xwall[nXWall].triggerImpact;
- dlgWall[14].value = xwall[nXWall].triggerReserved0;
- dlgWall[16].value = xwall[nXWall].decoupled;
- dlgWall[17].value = xwall[nXWall].triggerOnce;
- dlgWall[18].value = xwall[nXWall].locked;
- dlgWall[19].value = xwall[nXWall].interruptable;
- dlgWall[20].value = xwall[nXWall].data;
- dlgWall[21].value = xwall[nXWall].key;
- dlgWall[22].value = xwall[nXWall].panXVel;
- dlgWall[23].value = xwall[nXWall].panYVel;
- dlgWall[24].value = xwall[nXWall].panAlways;
- }
- /***********************************************************************
- * DialogToXWall()
- *
- **********************************************************************/
- void DialogToXWall( int nWall )
- {
- int nXWall = wall[nWall].extra;
- dassert(nXWall > 0 && nXWall < kMaxXWalls);
- wall[nWall].type= (short)dlgWall[0].value;
- xwall[nXWall].rxID= dlgWall[1].value;
- xwall[nXWall].txID= dlgWall[2].value;
- xwall[nXWall].state= dlgWall[3].value;
- xwall[nXWall].command= dlgWall[4].value;
- xwall[nXWall].triggerOn= dlgWall[6].value;
- xwall[nXWall].triggerOff= dlgWall[7].value;
- xwall[nXWall].busyTime= dlgWall[8].value;
- xwall[nXWall].waitTime= dlgWall[9].value;
- xwall[nXWall].restState= dlgWall[10].value;
- xwall[nXWall].triggerPush= dlgWall[12].value;
- xwall[nXWall].triggerImpact= dlgWall[13].value;
- xwall[nXWall].triggerReserved0= dlgWall[14].value;
- xwall[nXWall].decoupled= dlgWall[16].value;
- xwall[nXWall].triggerOnce= dlgWall[17].value;
- xwall[nXWall].locked= dlgWall[18].value;
- xwall[nXWall].interruptable= dlgWall[19].value;
- xwall[nXWall].data= dlgWall[20].value;
- xwall[nXWall].key= dlgWall[21].value;
- xwall[nXWall].panXVel= dlgWall[22].value;
- xwall[nXWall].panYVel= dlgWall[23].value;
- xwall[nXWall].panAlways= dlgWall[24].value;
- }
- /***********************************************************************
- * XSpriteToDialog()
- *
- **********************************************************************/
- void XSpriteToDialog( int nSprite )
- {
- int nXSprite = sprite[nSprite].extra;
- dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
- dlgSprite[0].value = sprite[nSprite].type;
- dlgSprite[1].value = xsprite[nXSprite].rxID;
- dlgSprite[2].value = xsprite[nXSprite].txID;
- dlgSprite[3].value = xsprite[nXSprite].state;
- dlgSprite[4].value = xsprite[nXSprite].command;
- dlgSprite[6].value = xsprite[nXSprite].triggerOn;
- dlgSprite[7].value = xsprite[nXSprite].triggerOff;
- dlgSprite[8].value = xsprite[nXSprite].busyTime;
- dlgSprite[9].value = xsprite[nXSprite].waitTime;
- dlgSprite[10].value = xsprite[nXSprite].restState;
- dlgSprite[12].value = xsprite[nXSprite].triggerPush;
- dlgSprite[13].value = xsprite[nXSprite].triggerImpact;
- dlgSprite[14].value = xsprite[nXSprite].triggerReserved0;
- dlgSprite[15].value = xsprite[nXSprite].triggerPickup;
- dlgSprite[16].value = xsprite[nXSprite].triggerTouch;
- dlgSprite[17].value = xsprite[nXSprite].triggerSight;
- dlgSprite[18].value = xsprite[nXSprite].triggerProximity;
- dlgSprite[20].value = xsprite[nXSprite].decoupled;
- dlgSprite[21].value = xsprite[nXSprite].triggerOnce;
- dlgSprite[22].value = xsprite[nXSprite].locked;
- dlgSprite[23].value = xsprite[nXSprite].interruptable;
- dlgSprite[24].value = xsprite[nXSprite].data1;
- dlgSprite[25].value = xsprite[nXSprite].data2;
- dlgSprite[26].value = xsprite[nXSprite].data3;
- dlgSprite[27].value = xsprite[nXSprite].key;
- dlgSprite[28].value = xsprite[nXSprite].soundId;
- dlgSprite[29].value = xsprite[nXSprite].difficulty;
- dlgSprite[31].value = xsprite[nXSprite].respawn;
- dlgSprite[32].value = xsprite[nXSprite].respawnTime;
- dlgSprite[34].value = xsprite[nXSprite].dudeDeaf;
- dlgSprite[35].value = xsprite[nXSprite].dudeAmbush;
- dlgSprite[36].value = xsprite[nXSprite].dudeGuard;
- dlgSprite[37].value = xsprite[nXSprite].dudeFlag4;
- }
- /***********************************************************************
- * DialogToXSprite()
- *
- **********************************************************************/
- void DialogToXSprite( int nSprite )
- {
- int nXSprite = sprite[nSprite].extra;
- dassert(nXSprite > 0 && nXSprite < kMaxXSprites);
- sprite[nSprite].type = (short)dlgSprite[0].value;
- xsprite[nXSprite].rxID = dlgSprite[1].value;
- xsprite[nXSprite].txID = dlgSprite[2].value;
- xsprite[nXSprite].state = dlgSprite[3].value;
- xsprite[nXSprite].command = dlgSprite[4].value;
- xsprite[nXSprite].triggerOn = dlgSprite[6].value;
- xsprite[nXSprite].triggerOff = dlgSprite[7].value;
- xsprite[nXSprite].busyTime = dlgSprite[8].value;
- xsprite[nXSprite].waitTime = dlgSprite[9].value;
- xsprite[nXSprite].restState = dlgSprite[10].value;
- xsprite[nXSprite].triggerPush = dlgSprite[12].value;
- xsprite[nXSprite].triggerImpact = dlgSprite[13].value;
- xsprite[nXSprite].triggerReserved0 = dlgSprite[14].value;
- xsprite[nXSprite].triggerPickup = dlgSprite[15].value;
- xsprite[nXSprite].triggerTouch = dlgSprite[16].value;
- xsprite[nXSprite].triggerSight = dlgSprite[17].value;
- xsprite[nXSprite].triggerProximity = dlgSprite[18].value;
- xsprite[nXSprite].decoupled = dlgSprite[20].value;
- xsprite[nXSprite].triggerOnce = dlgSprite[21].value;
- xsprite[nXSprite].locked = dlgSprite[22].value;
- xsprite[nXSprite].interruptable = dlgSprite[23].value;
- xsprite[nXSprite].data1 = dlgSprite[24].value;
- xsprite[nXSprite].data2 = dlgSprite[25].value;
- xsprite[nXSprite].data3 = dlgSprite[26].value;
- xsprite[nXSprite].key = dlgSprite[27].value;
- xsprite[nXSprite].soundId = dlgSprite[28].value;
- xsprite[nXSprite].difficulty = dlgSprite[29].value;
- xsprite[nXSprite].respawn = dlgSprite[31].value;
- xsprite[nXSprite].respawnTime = dlgSprite[32].value;
- xsprite[nXSprite].dudeDeaf= dlgSprite[34].value;
- xsprite[nXSprite].dudeAmbush= dlgSprite[35].value;
- xsprite[nXSprite].dudeGuard= dlgSprite[36].value;
- xsprite[nXSprite].dudeFlag4= dlgSprite[37].value;
- }
- /***********************************************************************
- * XSectorToDialog()
- *
- **********************************************************************/
- void XSectorToDialog( int nSector )
- {
- int nXSector = sector[nSector].extra;
- dassert(nXSector > 0 && nXSector < kMaxXSectors);
- dlgSector[0].value = (short)sector[nSector].type;
- dlgSector[1].value = xsector[nXSector].rxID;
- dlgSector[2].value = xsector[nXSector].txID;
- dlgSector[3].value = xsector[nXSector].state;
- dlgSector[4].value = xsector[nXSector].command;
- dlgSector[6].value = xsector[nXSector].triggerOn;
- dlgSector[7].value = xsector[nXSector].triggerOff;
- dlgSector[8].value = xsector[nXSector].busyTime;
- dlgSector[9].value = xsector[nXSector].waitTime;
- dlgSector[10].value = xsector[nXSector].restState;
- dlgSector[12].value = xsector[nXSector].triggerPush;
- dlgSector[13].value = xsector[nXSector].triggerImpact;
- dlgSector[14].value = xsector[nXSector].triggerReserved0;
- dlgSector[15].value = xsector[nXSector].triggerEnter;
- dlgSector[16].value = xsector[nXSector].triggerExit;
- dlgSector[17].value = xsector[nXSector].triggerWPush;
- dlgSector[19].value = xsector[nXSector].decoupled;
- dlgSector[20].value = xsector[nXSector].triggerOnce;
- dlgSector[21].value = xsector[nXSector].locked;
- dlgSector[22].value = xsector[nXSector].interruptable;
- dlgSector[23].value = xsector[nXSector].data;
- dlgSector[24].value = xsector[nXSector].key;
- dlgSectorFX[1].value = xsector[nXSector].wave;
- dlgSectorFX[2].value = xsector[nXSector].amplitude;
- dlgSectorFX[3].value = xsector[nXSector].freq;
- dlgSectorFX[4].value = xsector[nXSector].phase;
- dlgSectorFX[5].value = xsector[nXSector].shadeFloor;
- dlgSectorFX[6].value = xsector[nXSector].shadeCeiling;
- dlgSectorFX[7].value = xsector[nXSector].shadeWalls;
- dlgSectorFX[8].value = xsector[nXSector].shadeAlways;
- dlgSectorFX[10].value = xsector[nXSector].panVel;
- dlgSectorFX[11].value = xsector[nXSector].panAngle;
- dlgSectorFX[12].value = xsector[nXSector].panFloor;
- dlgSectorFX[13].value = xsector[nXSector].panCeiling;
- dlgSectorFX[14].value = xsector[nXSector].panAlways;
- dlgSectorFX[15].value = xsector[nXSector].drag;
- dlgSectorFX[16].value = xsector[nXSector].depth;
- dlgSectorFX[17].value = xsector[nXSector].underwater;
- dlgSectorFX[18].value = xsector[nXSector].wind;
- }
- /***********************************************************************
- * DialogToXSector()
- *
- **********************************************************************/
- void DialogToXSector( int nSector )
- {
- int nXSector = sector[nSector].extra;
- dassert(nXSector > 0 && nXSector < kMaxXSectors);
- sector[nSector].type = (short)dlgSector[0].value;
- xsector[nXSector].rxID = dlgSector[1].value;
- xsector[nXSector].txID = dlgSector[2].value;
- xsector[nXSector].state = dlgSector[3].value;
- xsector[nXSector].command = dlgSector[4].value;
- xsector[nXSector].triggerOn = dlgSector[6].value;
- xsector[nXSector].triggerOff = dlgSector[7].value;
- xsector[nXSector].busyTime = dlgSector[8].value;
- xsector[nXSector].waitTime = dlgSector[9].value;
- xsector[nXSector].restState = dlgSector[10].value;
- xsector[nXSector].triggerPush = dlgSector[12].value;
- xsector[nXSector].triggerImpact = dlgSector[13].value;
- xsector[nXSector].triggerReserved0 = dlgSector[14].value;
- xsector[nXSector].triggerEnter = dlgSector[15].value;
- xsector[nXSector].triggerExit = dlgSector[16].value;
- xsector[nXSector].triggerWPush = dlgSector[17].value;
- xsector[nXSector].decoupled = dlgSector[19].value;
- xsector[nXSector].triggerOnce = dlgSector[20].value;
- xsector[nXSector].locked = dlgSector[21].value;
- xsector[nXSector].interruptable = dlgSector[22].value;
- xsector[nXSector].data = dlgSector[23].value;
- xsector[nXSector].key = dlgSector[24].value;
- xsector[nXSector].wave = dlgSectorFX[1].value;
- xsector[nXSector].amplitude = dlgSectorFX[2].value;
- xsector[nXSector].freq = dlgSectorFX[3].value;
- xsector[nXSector].phase = dlgSectorFX[4].value;
- xsector[nXSector].shadeFloor = dlgSectorFX[5].value;
- xsector[nXSector].shadeCeiling = dlgSectorFX[6].value;
- xsector[nXSector].shadeWalls = dlgSectorFX[7].value;
- xsector[nXSector].shadeAlways = dlgSectorFX[8].value;
- xsector[nXSector].panVel = dlgSectorFX[10].value;
- xsector[nXSector].panAngle = dlgSectorFX[11].value;
- xsector[nXSector].panFloor = dlgSectorFX[12].value;
- xsector[nXSector].panCeiling = dlgSectorFX[13].value;
- xsector[nXSector].panAlways = dlgSectorFX[14].value;
- xsector[nXSector].drag = dlgSectorFX[15].value;
- xsector[nXSector].depth = dlgSectorFX[16].value;
- xsector[nXSector].underwater = dlgSectorFX[17].value;
- xsector[nXSector].wind = dlgSectorFX[18].value;
- }
- int getpointhighlight(int x, int y)
- {
- long i, d, closest, n;
- closest = divscale(gHighlightThreshold, zoom, 14);
- n = -1;
- for (i = 0; i < kMaxSprites; i++)
- {
- if (sprite[i].statnum < kMaxStatus)
- {
- d = qdist(x - sprite[i].x, y - sprite[i].y);
- if (d < closest)
- {
- closest = d;
- n = i | 0x4000;
- }
- }
- }
- for (i = 0; i < numwalls; i++)
- {
- d = qdist(x - wall[i].x, y - wall[i].y);
- if (d < closest)
- {
- closest = d;
- n = i;
- }
- }
- return n;
- }
- /***********************************************************************
- * ShowSectorData()
- *
- * This function displays the game specific sector data in the status
- * area.
- **********************************************************************/
- void ShowSectorData( int nSector )
- {
- int nXSector;
- dassert(nSector >= 0 && nSector < kMaxSectors);
- sprintf(buffer, "Sector %d", nSector);
- printmessage16(buffer);
- if (sector[nSector].extra != -1)
- {
- nXSector = sector[nSector].extra;
- dassert(nXSector < kMaxXSectors);
- XSectorToDialog(nSector);
- PaintDialog(dlgSector, LENGTH(dlgSector));
- }
- else
- clearmidstatbar16();
- }
- /***********************************************************************
- * EditSectorData()
- *
- * This function allows editing of the game specific sector data.
- **********************************************************************/
- void EditSectorData( int nSector )
- {
- int nXSector;
- dassert(nSector >= 0 && nSector < kMaxSectors);
- CleanUp();
- sprintf(buffer, "Sector %d", nSector);
- printmessage16(buffer);
- nXSector = GetXSector(nSector);
- XSectorToDialog(nSector);
- if ( EditDialog(dlgSector, LENGTH(dlgSector)) )
- DialogToXSector(nSector);
- ShowSectorData(nSector);
- vel = svel = angvel = 0;
- CleanUp();
- }
- /***********************************************************************
- * ShowWallData()
- *
- * This function displays the game specific wall data in the status
- * area.
- **********************************************************************/
- void ShowWallData( int nWall )
- {
- int nXWall;
- dassert(nWall >= 0 && nWall < kMaxWalls);
- int nWall2 = wall[nWall].point2;
- int length = qdist(wall[nWall2].x - wall[nWall].x, wall[nWall2].y - wall[nWall].y);
- sprintf(buffer, "Wall %d: Length = %d", nWall, length);
- printmessage16(buffer);
- if (wall[nWall].extra != -1)
- {
- nXWall = wall[nWall].extra;
- dassert(nXWall < kMaxXWalls);
- XWallToDialog(nWall);
- PaintDialog(dlgWall, LENGTH(dlgWall));
- }
- else
- {
- clearmidstatbar16();
- }
- }
- /***********************************************************************
- * EditWallData()
- *
- * This function allows editing of the game specific wall data.
- **********************************************************************/
- void EditWallData( int nWall )
- {
- int nXWall;
- dassert(nWall >= 0 && nWall < kMaxWalls);
- CleanUp();
- sprintf(buffer, "Wall %d", nWall);
- printmessage16(buffer);
- nXWall = GetXWall(nWall);
- XWallToDialog(nWall);
- if ( EditDialog(dlgWall, LENGTH(dlgWall)) )
- DialogToXWall(nWall);
- ShowWallData(nWall);
- vel = svel = angvel = 0;
- CleanUp();
- }
- /***********************************************************************
- * ShowSpriteData()
- *
- * This function displays the game specific sprite data in the status
- * area.
- **********************************************************************/
- void ShowSpriteData( int nSprite )
- {
- int nXSprite;
- dassert(nSprite >= 0 && nSprite < kMaxSprites);
- if (sprite[nSprite].extra > 0)
- {
- nXSprite = sprite[nSprite].extra;
- sprintf(buffer, "Sprite %d Extra %d XRef %d",
- nSprite, nXSprite, xsprite[nXSprite].reference);
- }
- else
- {
- sprintf(buffer, "Sprite %d", nSprite);
- }
- printmessage16(buffer);
- if ( sprite[nSprite].extra > 0 )
- {
- nXSprite = sprite[nSprite].extra;
- dassert(nXSprite < kMaxXSprites);
- XSpriteToDialog(nSprite);
- PaintDialog(dlgSprite, LENGTH(dlgSprite));
- }
- else
- clearmidstatbar16();
- }
- /***********************************************************************
- * EditSpriteData()
- *
- * This function allows editing of the game specific sprite data.
- **********************************************************************/
- void EditSpriteData( int nSprite )
- {
- int nXSprite;
- dassert(nSprite >= 0 && nSprite < kMaxSprites);
- CleanUp();
- sprintf(buffer, "Sprite %d", nSprite);
- printmessage16(buffer);
- nXSprite = GetXSprite(nSprite);
- XSpriteToDialog(nSprite);
- if ( EditDialog(dlgSprite, LENGTH(dlgSprite)) )
- DialogToXSprite(nSprite);
- ShowSpriteData(nSprite);
- vel = svel = angvel = 0;
- CleanUp();
- // fix sprite type attributes
- AutoAdjustSprites();
- }
- int getlinehighlight(int x, int y)
- {
- long i, dst, dist, closest, xi, yi;
- dist = divscale(gHighlightThreshold, zoom, 14);
- closest = -1;
- for (i = 0; i < numwalls; i++)
- {
- int lx = wall[wall[i].point2].x - wall[i].x;
- int ly = wall[wall[i].point2].y - wall[i].y;
- int qx = x - wall[i].x;
- int qy = y - wall[i].y;
- // is point on wrong side of wall?
- if ( qx * ly > qy * lx )
- continue;
- int num = dmulscale(qx, lx, qy, ly, 4);
- int den = dmulscale(lx, lx, ly, ly, 4);
- if (num <= 0 || num >= den)
- continue;
- xi = wall[i].x + muldiv(lx, num, den);
- yi = wall[i].y + muldiv(ly, num, den);
- dst = qdist(xi - x, yi - y);
- if (dst <= dist)
- {
- dist = dst;
- closest = i;
- }
- }
- return closest;
- }
- void setcolor16(int color);
- #pragma aux setcolor16 =\
- "mov dx, 0x3ce",\
- "shl ax, 8",\
- "out dx, ax",\
- parm [eax]\
- void drawpixel16(int offset);
- #pragma aux drawpixel16 =\
- "mov ecx, edi",\
- "and cl, 7",\
- "xor cl, 7",\
- "mov ah, 1",\
- "shl ah, cl",\
- "mov dx, 0x3ce",\
- "mov al, 0x8",\
- "out dx, ax",\
- "shr edi, 3",\
- "or byte ptr [edi+0xA0000], al",\
- parm [edi]\
- modify [eax ecx edx]\
- void Draw2dWall( int x0, int y0, int x1, int y1, char color, int thick )
- {
- if ( x0 < 0 && x1 < 0 ) return;
- if ( x0 >= 640 && x1 >= 640 ) return;
- if ( y0 < 0 && y1 < 0 ) return;
- if ( y0 >= ydim16 && y1 >= ydim16 ) return;
- drawline16(x0, y0, x1, y1, color);
- if (thick)
- {
- long dx = x1 - x0;
- long dy = y1 - y0;
- RotateVector(&dx, &dy, kAngle45 / 2);
- switch (GetOctant(dx, dy))
- {
- case 0:
- case 4:
- drawline16(x0, y0-1, x1, y1-1, color);
- drawline16(x0, y0+1, x1, y1+1, color);
- break;
- case 1:
- case 5:
- if (qabs(dx) < qabs(dy) )
- {
- drawline16(x0-1, y0+1, x1-1, y1+1, color);
- drawline16(x0-1, y0, x1, y1+1, color);
- drawline16(x0+1, y0, x1+1, y1, color);
- }
- else
- {
- drawline16(x0-1, y0+1, x1-1, y1+1, color);
- drawline16(x0, y0+1, x1, y1+1, color);
- drawline16(x0, y0+1, x1, y1+1, color);
- }
- break;
- case 2:
- case 6:
- drawline16(x0-1, y0, x1-1, y1, color);
- drawline16(x0+1, y0, x1+1, y1, color);
- break;
- case 3:
- case 7:
- if (qabs(dx) < qabs(dy) )
- {
- drawline16(x0-1, y0-1, x1-1, y1-1, color);
- drawline16(x0-1, y0, x1-1, y1, color);
- drawline16(x0+1, y0, x1+1, y1, color);
- }
- else
- {
- drawline16(x0-1, y0-1, x1-1, y1-1, color);
- drawline16(x0, y0-1, x1, y1-1, color);
- drawline16(x0, y0+1, x1, y1+1, color);
- }
- break;
- }
- }
- }
- void Draw2dVertex( int x, int y, int color )
- {
- long templong = y * 640 + x + pageoffset;
- setcolor16(color);
- drawpixel16(templong-2-1280);
- drawpixel16(templong-1-1280);
- drawpixel16(templong+0-1280);
- drawpixel16(templong+1-1280);
- drawpixel16(templong+2-1280);
- drawpixel16(templong-2-640);
- drawpixel16(templong-2+0);
- drawpixel16(templong-2+640);
- drawpixel16(templong+2-640);
- drawpixel16(templong+2+0);
- drawpixel16(templong+2+640);
- drawpixel16(templong-2+1280);
- drawpixel16(templong-1+1280);
- drawpixel16(templong+0+1280);
- drawpixel16(templong+1+1280);
- drawpixel16(templong+2+1280);
- }
- void Draw2dFaceSprite( int x, int y, int color)
- {
- long templong = y * 640 + x + pageoffset;
- setcolor16(color);
- drawpixel16(templong - 1 - 1920);
- drawpixel16(templong + 0 - 1920);
- drawpixel16(templong + 1 - 1920);
- drawpixel16(templong - 2 - 1280);
- drawpixel16(templong + 2 - 1280);
- drawpixel16(templong - 3 - 640);
- drawpixel16(templong + 3 - 640);
- drawpixel16(templong - 3 + 0);
- drawpixel16(templong + 3 + 0);
- drawpixel16(templong - 3 + 640);
- drawpixel16(templong + 3 + 640);
- drawpixel16(templong - 2 + 1280);
- drawpixel16(templong + 2 + 1280);
- drawpixel16(templong - 1 + 1920);
- drawpixel16(templong + 0 + 1920);
- drawpixel16(templong + 1 + 1920);
- }
- void Draw2dFloorSprite( int x, int y, char color)
- {
- drawline16(x - 3, y - 3, x + 3, y - 3, color);
- drawline16(x - 3, y + 3, x + 3, y + 3, color);
- drawline16(x - 3, y - 3, x - 3, y + 3, color);
- drawline16(x + 3, y - 3, x + 3, y + 3, color);
- }
- void Draw2dMarker( int x, int y, int color)
- {
- long templong = y * 640 + x + pageoffset;
- setcolor16(color);
- drawpixel16(templong - 1 - 2560);
- drawpixel16(templong + 0 - 2560);
- drawpixel16(templong + 1 - 2560);
- drawpixel16(templong - 3 - 1920);
- drawpixel16(templong - 2 - 1920);
- drawpixel16(templong + 2 - 1920);
- drawpixel16(templong + 3 - 1920);
- drawpixel16(templong - 3 - 1280);
- drawpixel16(templong - 2 - 1280);
- drawpixel16(templong + 2 - 1280);
- drawpixel16(templong + 3 - 1280);
- drawpixel16(templong - 4 - 640);
- drawpixel16(templong - 1 - 640);
- drawpixel16(templong + 1 - 640);
- drawpixel16(templong + 4 - 640);
- drawpixel16(templong - 4);
- drawpixel16(templong + 0);
- drawpixel16(templong + 4);
- drawpixel16(templong - 4 + 640);
- drawpixel16(templong - 1 + 640);
- drawpixel16(templong + 1 + 640);
- drawpixel16(templong + 4 + 640);
- drawpixel16(templong - 3 + 1280);
- drawpixel16(templong - 2 + 1280);
- drawpixel16(templong + 2 + 1280);
- drawpixel16(templong + 3 + 1280);
- drawpixel16(templong - 3 + 1920);
- drawpixel16(templong - 2 + 1920);
- drawpixel16(templong + 2 + 1920);
- drawpixel16(templong + 3 + 1920);
- drawpixel16(templong - 1 + 2560);
- drawpixel16(templong + 0 + 2560);
- drawpixel16(templong + 1 + 2560);
- }
- void draw2dscreen(long x, long y, short nAngle, long nZoom, short nGrid )
- {
- int i, j, x0, y0, x1, y1;
- char nColor;
- char h = (gFrameClock & 0x08) ? 8 : 0;
- int thick;
- short flags;
- // steal a copy of these variables, because Ken made them static!
- grid = nGrid;
- zoom = nZoom;
- if (qsetmode == 200)
- return;
- for (i = 0; i < numwalls; i++)
- {
- // only draw one side of walls
- if ( wall[i].nextwall > i)
- continue;
- if (wall[i].nextwall == -1)
- {
- nColor = kColorWhite;
- flags = wall[i].cstat;
- thick = 0;
- }
- else
- {
- nColor = kColorRed;
- thick = 0;
- flags = wall[i].cstat | wall[wall[i].nextwall].cstat;
- // if one side is highlighted, only show that side's flags
- if (i == linehighlight)
- flags = wall[i].cstat;
- else if (wall[i].nextwall == linehighlight)
- flags = wall[wall[i].nextwall].cstat;
- if ( flags & kWallHitscan)
- nColor = kColorMagenta;
- if ( flags & kWallBlocking)
- thick = 1;
- }
- if ( flags & kWallMoveForward )
- nColor = kColorLightBlue;
- if ( flags & kWallMoveBackward )
- nColor = kColorLightGreen;
- if ( linehighlight >= 0 && (i == linehighlight || wall[i].nextwall == linehighlight) )
- nColor ^= h;
- x0 = 320 + mulscale(wall[i].x - x, nZoom, 14);
- y0 = 200 + mulscale(wall[i].y - y, nZoom, 14);
- x1 = 320 + mulscale(wall[wall[i].point2].x - x, nZoom, 14);
- y1 = 200 + mulscale(wall[wall[i].point2].y - y, nZoom, 14);
- Draw2dWall( x0, y0, x1, y1, nColor, thick);
- if (nZoom >= 256 && x0 > 4 && x0 < 635 && y0 > 4 && y0 < ydim16-5 )
- Draw2dVertex(x0, y0, kColorBrown);
- }
- // redraw highlighted vertices
- if (nZoom >= 256)
- {
- for (i = 0; i < numwalls; i++)
- {
- if ( i == pointhighlight || (highlightcnt > 0 && TestBitString(show2dwall, i)) )
- {
- x0 = 320 + mulscale(wall[i].x - x, nZoom, 14);
- y0 = 200 + mulscale(wall[i].y - y, nZoom, 14);
- if ( x0 > 4 && x0 < 635 && y0 > 4 && y0 < ydim16-5 )
- Draw2dVertex(x0, y0, kColorBrown ^ h);
- }
- }
- }
- if (nZoom >= 256)
- {
- for (i = 0; i < numsectors; i++)
- {
- j = headspritesect[i];
- while (j != -1)
- {
- x0 = 320 + mulscale(sprite[j].x - x, nZoom, 14);
- y0 = 200 + mulscale(sprite[j].y - y, nZoom, 14);
- if ( sprite[j].statnum == kStatMarker )
- {
- nColor = kColorYellow;
- if ( sprite[j].owner == sectorhighlight )
- nColor = kColorWhite;
- if ((j | 0x4000) == pointhighlight || (highlightcnt > 0 && TestBitString(show2dsprite, j)) )
- nColor ^= h;
- if (x0 > 4 && x0 < 635 && y0 > 4 && y0 < ydim16-5)
- switch( sprite[j].type )
- {
- case kMarkerOff:
- case kMarkerOn:
- Draw2dMarker(x0, y0, nColor);
- break;
- case kMarkerWarpDest:
- case kMarkerAxis:
- Draw2dMarker(x0, y0, nColor);
- x1 = mulscale30(nZoom / 128, Cos(sprite[j].ang));
- y1 = mulscale30(nZoom / 128, Sin(sprite[j].ang));
- Draw2dWall(x0, y0, x0 + x1, y0 + y1, nColor, thick);
- break;
- }
- if ( sprite[j].type == kMarkerOff )
- {
- // draw movement arrow
- int nSector = sprite[j].owner;
- int nXSector = sector[nSector].extra;
- dassert(nXSector > 0 && nXSector < kMaxXSectors);
- int nSprite2 = xsector[nXSector].marker1;
- x1 = 320 + mulscale(sprite[nSprite2].x - x, nZoom, 14);
- y1 = 200 + mulscale(sprite[nSprite2].y - y, nZoom, 14);
- drawline16(x0, y0, x1, y1, kColorLightBlue);
- int nAngle = getangle(x0 - x1, y0 - y1);
- x0 = mulscale30(nZoom / 64, Cos(nAngle + kAngle30));
- y0 = mulscale30(nZoom / 64, Sin(nAngle + kAngle30));
- drawline16(x1, y1, x1 + x0, y1 + y0, kColorLightBlue);
- x0 = mulscale30(nZoom / 64, Cos(nAngle - kAngle30));
- y0 = mulscale30(nZoom / 64, Sin(nAngle - kAngle30));
- drawline16(x1, y1, x1 + x0, y1 + y0, kColorLightBlue);
- }
- }
- else
- {
- nColor = kColorCyan;
- thick = 0;
- if ( sprite[j].cstat & kSpriteHitscan )
- nColor = kColorMagenta;
- if ( sprite[j].cstat & kSpriteMoveForward )
- nColor = kColorLightBlue;
- if ( sprite[j].cstat & kSpriteMoveReverse )
- nColor = kColorLightGreen;
- if ( sprite[j].cstat & kSpriteBlocking )
- thick = 1;
- if ((j | 0x4000) == pointhighlight || (highlightcnt > 0 && TestBitString(show2dsprite, j)) )
- nColor ^= h;
- if (x0 > 4 && x0 < 635 && y0 > 4 && y0 < ydim16-5)
- {
- switch (sprite[j].cstat & kSpriteRMask)
- {
- case kSpriteFace:
- case kSpriteSpin:
- Draw2dFaceSprite(x0, y0, nColor);
- x1 = mulscale30(nZoom / 128, Cos(sprite[j].ang));
- y1 = mulscale30(nZoom / 128, Sin(sprite[j].ang));
- Draw2dWall(x0, y0, x0 + x1, y0 + y1, nColor, thick);
- break;
- case kSpriteWall:
- Draw2dFaceSprite(x0, y0, nColor);
- x1 = mulscale30(nZoom / 128, Cos(sprite[j].ang + kAngle90));
- y1 = mulscale30(nZoom / 128, Sin(sprite[j].ang + kAngle90));
- Draw2dWall(x0 - x1, y0 - y1, x0 + x1, y0 + y1, nColor, thick);
- x1 = mulscale30(nZoom / 256, Cos(sprite[j].ang));
- y1 = mulscale30(nZoom / 256, Sin(sprite[j].ang));
- if (sprite[j].cstat & kSpriteOneSided)
- Draw2dWall(x0, y0, x0 + x1, y0 + y1, nColor, thick);
- else
- Draw2dWall(x0 - x1, y0 - y1, x0 + x1, y0 + y1, nColor, thick);
- break;
- case kSpriteFloor:
- Draw2dFloorSprite(x0, y0, nColor);
- x1 = mulscale30(nZoom / 256, Cos(sprite[j].ang));
- y1 = mulscale30(nZoom / 256, Sin(sprite[j].ang));
- Draw2dWall(x0, y0, x0 + x1, y0 + y1, nColor, thick);
- break;
- }
- }
- }
- j = nextspritesect[j];
- }
- }
- }
- x0 = 320 + mulscale30(nZoom / 128, Cos(nAngle)); //Draw white arrow
- y0 = 200 + mulscale30(nZoom / 128, Sin(nAngle));
- drawline16(x0, y0, 640-x0,400-y0,kColorWhite);
- drawline16(x0, y0, 120+y0,520-x0,kColorWhite);
- drawline16(x0, y0, 520-y0,-120+x0,kColorWhite);
- }
- void ProcessKeys2D( void )
- {
- BYTE key;
- BYTE shift, ctrl, alt;
- int x, y;
- static int nPointLast = -1, nLineLast = -1, nSectorLast = -1;
- static int oldnumwalls, oldnumsectors, oldnumsprites;
- int numsprites = 0;
- // redetermine numsprites (build.c version is static!)
- numsprites = 0;
- for (int i = 0; i < kMaxSprites; i++)
- if ( sprite[i].statnum < kMaxStatus )
- numsprites++;
- // did anything important happen?
- if (numwalls != oldnumwalls || numsectors != oldnumsectors || numsprites != oldnumsprites)
- {
- CleanUp();
- // fix sprite type attributes
- AutoAdjustSprites();
- oldnumwalls = numwalls;
- oldnumsectors = numsectors;
- oldnumsprites = numsprites;
- }
- shift = keystatus[KEY_LSHIFT] | keystatus[KEY_RSHIFT];
- ctrl = keystatus[KEY_LCTRL] | keystatus[KEY_RCTRL];
- alt = keystatus[KEY_LALT] | keystatus[KEY_RALT];
- getpoint(searchx, searchy, &x, &y);
- updatesector(x, y, §orhighlight);
- if (pointhighlight != nPointLast || linehighlight != nLineLast || sectorhighlight != nSectorLast)
- {
- nPointLast = pointhighlight;
- nLineLast = linehighlight;
- nSectorLast = sectorhighlight;
- if ((pointhighlight & 0xC000) == 0x4000)
- ShowSpriteData(pointhighlight & 0x3FFF);
- else if (linehighlight >= 0)
- ShowWallData(linehighlight);
- else if (sectorhighlight >= 0)
- ShowSectorData(sectorhighlight);
- else
- clearmidstatbar16();
- }
- key = keyGet();
- switch (key)
- {
- case KEY_HOME:
- if (ctrl)
- {
- short nSprite = getnumber16("Locate sprite #: ",0,kMaxSprites);
- clearmidstatbar16();
- if (nSprite >= 0 && nSprite < kMaxSprites && sprite[nSprite].statnum < kMaxStatus)
- {
- posx = sprite[nSprite].x;
- posy = sprite[nSprite].y;
- posz = sprite[nSprite].z;
- ang = sprite[nSprite].ang;
- cursectnum = sprite[nSprite].sectnum;
- }
- else
- printmessage16("Sir Not Appearing In This Film");
- }
- break;
- case KEY_K: // Kinetic sprites/walls
- if ( (pointhighlight & 0xC000) == 0x4000 ) // is a sprite highlighted
- {
- short flags = (short)(sprite[pointhighlight & 0x3FFF].cstat & kSpriteMoveMask);
- switch (flags)
- {
- case kSpriteMoveNone:
- flags = kSpriteMoveForward;
- break;
- case kSpriteMoveForward:
- flags = kSpriteMoveReverse;
- break;
- case kSpriteMoveReverse:
- flags = kSpriteMoveNone;
- break;
- default:
- flags = kSpriteMoveNone;
- }
- sprite[pointhighlight & 0x3FFF].cstat &= ~kSpriteMoveMask;
- sprite[pointhighlight & 0x3FFF].cstat |= flags;
- BeepOkay();
- }
- else if ( linehighlight >=0 )
- {
- short flags = (short)(wall[linehighlight].cstat & kWallMoveMask);
- switch (flags)
- {
- case kWallMoveNone:
- flags = kWallMoveForward;
- break;
- case kWallMoveForward:
- flags = kWallMoveBackward;
- break;
- case kWallMoveBackward:
- flags = kWallMoveNone;
- break;
- default:
- flags = kWallMoveNone;
- }
- wall[linehighlight].cstat &= ~kWallMoveMask;
- wall[linehighlight].cstat |= flags;
- BeepOkay();
- }
- else
- BeepError();
- break;
- case KEY_M: // Masked walls
- if ( linehighlight >=0 )
- {
- int nWall = linehighlight;
- int nWall2 = wall[nWall].nextwall;
- if (nWall2 < 0)
- {
- BeepError();
- break;
- }
- wall[nWall].cstat |= kWallMasked;
- wall[nWall].cstat &= ~kWallFlipX;
- wall[nWall2].cstat |= kWallFlipX; //auto other-side flip
- wall[nWall2].cstat |= kWallMasked;
- if (wall[nWall].overpicnum < 0)
- wall[nWall].overpicnum = 0;
- wall[nWall2].overpicnum = wall[nWall].overpicnum;
- wall[nWall].cstat &= ~kWallOneWay;
- wall[nWall2].cstat &= ~kWallOneWay;
- sprintf(buffer, "wall[%i] %s masked", searchwall,
- (wall[searchwall].cstat & kWallMasked) ? "is" : "not");
- printmessage16(buffer);
- BeepOkay();
- break;
- }
- else
- BeepError();
- break;
- case KEY_LBRACE:
- if ( (pointhighlight & 0xC000) == 0x4000 ) // is a sprite highlighted
- {
- int nSprite = pointhighlight & 0x3FFF;
- // rotate sprite ccw
- int step = shift ? 16 : 256;
- sprite[nSprite].ang = (short)DecNext(sprite[nSprite].ang, step);
- sprintf(buffer, "sprite[%i].ang: %i", nSprite, sprite[nSprite].ang);
- printmessage16(buffer);
- BeepOkay();
- }
- break;
- case KEY_RBRACE:
- if ( (pointhighlight & 0xC000) == 0x4000 ) // is a sprite highlighted
- {
- int nSprite = pointhighlight & 0x3FFF;
- // rotate sprite ccw
- int step = shift ? 16 : 256;
- sprite[nSprite].ang = (short)IncNext(sprite[nSprite].ang, step);
- sprintf(buffer, "sprite[%i].ang: %i", nSprite, sprite[nSprite].ang);
- printmessage16(buffer);
- BeepOkay();
- }
- break;
- }
- // let's see if this fixes the input buffering problem
- if (key != 0)
- keyFlushStream();
- }
|